A Primer on Design Patterns
A Primer on Design Patterns
Rahul Batra
Buy on Leanpub

Preface

Welcome to the first edition of A Primer on Design Patterns. Its my third book in the Primer series and I must say I am loving the experience. I hope you have an equally good time with this text. I’ve tried my best to keep it easy to read and crisp at the same time.

This is my first text that expects a good grasp of programming before you attempt to read it. The reader is expected to be a beginner level programmer in an object oriented language like Java or Python. The objective of the book is to introduce its reader to the world of design patterns by working through some important ones. It is by no means an exaustive reference to all the design patterns out there.

Your questions, comments, criticism, encouragement and corrections are most welcome and you can e-mail me at rhlbatra[aht]hotmail[dot]com. I’ll try answering all on-topic mails and will try to include suggestions, errors and omissions in future editions.

Rahul Batra (22nd March 2016)

About the author

Rahul Batra was first introduced to programming during 1996 in GWBASIC, but he did not seriously foray into it till 2001 when he started learning C++. Along the way, there were dabblings in many other languages like Python, Ruby, Perl and Java. He has worked in many domains like enterprise backup, ad-tech, financial softwares and analytics.

Rahul has been programming professionally since 2006 and currently lives and works in Gurgaon, India.

Acknowledgements

This book has been a challenge and it would not be in its present form without the support of family and friends. I would like to acknowledge my son Vedant for this - he has given me such joy, and such purpose in life that I will be forever grateful to him even if he doesn’t know it yet. You are everything to me.

I am also eternally grateful to my parents who made many sacrifices so that I can have the best of education and resources. I owe my life’s work to them.

Introducing Design Patterns

What are design patterns?

Experience is a great teacher. Suppose you follow this maxim and note down all the great ways you solve common problems that crop up in your day-to-day coding tasks. A decade into your programming life, you would have a neat set of solutions that fit elegantly as solutions to said problems. You have just created a set of design patterns for yourself.

It is not only easier, but also more efficient, to stand on the shoulders of giants, so to speak. Programmers have combined and collected design patterns over the decades, ready for you to consume. These solutions to everyday coding problems make your code not only elegant, extensible and readable.

History of design patterns

The first work to explicitly collect and present object oriented design patterns was a book called Design Patterns: Elements of Reusable Object-Oriented Software by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides in 1994. This book and the 23 patterns discussed therein became so popular that they are referred to as the Gang of Four (GoF) book and GoF patterns respectively.

Pattern Name Category
Abstract Factory Creational
Builder Creational
Factory Method Creational
Prototype Creational
Singleton Creational
Adapter Structural
Bridge Structural
Composite Structural
Decorator Structural
Facade Structural
Flyweight Structural
Proxy Structural
Chain of Responsibility Behavioral
Command Behavioral
Interpreter Behavioral
Iterator Behavioral
Mediator Behavioral
Memento Behavioral
Observer Behavioral
State Behavioral
Strategy Behavioral
Template Method Behavioral
Visitor Behavioral

Not all GoF patterns gained equal acceptance in the programming community. Some were used more than the others. New patterns have been created since the book was first published. However, quite a few of these patterns remain in widespread use today. We will study a subset of the most important design patterns in the chapters that follow.

The language choice

Since we are going to study object oriented design patterns, it is natural to choose a language that adheres to the OO paradigm. Due to its popularity, I have chosen Java as one of the languages to demonstrate the principles of design patterns. However, in some cases, the verbosity of Java leads us away from the core explaination of the pattern and into the innards of language constructs. In such cases, I have decided to remove chunks of boilerplate code which do not illustrate the key points of the pattern being discussed, while still keeping the code Java-like.

The implementation and usefullness of a design pattern varies wildly from language to language. So it would be good to compare the patterns implementation in a contrasting language like Python whose dynamic nature and programming philosophy is quite orthogonal to Java.

Pattern abuse

Knowing design patterns is not a substitute for programming taste. If you read this text, or any text on design patterns, as an approach to how all code must be designed, you are likely to fall into the pattern abuse habit.

Since the GoF book came out 2 decades ago, there has been much discussion on patterns and they are now accepted as a good thing on balance. But is has also frequently led to over-engineering of software by cramming as many design patterns as one can in the code. You must strive to avoid this trap by using design patterns judiciously and recognising them for what they are - good solutions to common design problems in certain but not all scenario’s.

Strategy Pattern

In this chapter we take an example of a batch task processing system - a system where jobs or tasks are put in a queue and executed one by one. Multiple task runners may be instantiated and they pick up the next task to be completed from a queue. Selecting the next task can be unique to each task runner. They may use a first come, first serve algorithm to pick up the task. They may also use complex algorithms like shortest task first or priority based tasks.

Inheritance might not be your best friend

If you emphasize on inheritance in your object oriented design, you might design an inheritance hierarchy for this as below.

Listing: the task runner class hierarchy
 1 public class TaskRunner {
 2   void getNextTask() {
 3     //Skeleton method
 4   }
 5   
 6   //Other variables and methods
 7 }
 8 
 9 public class ShortestJobRunner extends TaskRunner {
10   void getNextTask() {
11     //Implementation of the shortest job first algorithm
12     ...
13   } 
14 }
15 
16 //Other similar classes extending TaskRunner
17 ...

If you have many such classes, you have spread your getNextTask() algorithm over multiple generations of classes. Frequent changes to these make the patching cumbersome and the design brittle. What if you want to create two different ShortestJobRunner’s - one that can handle task pre-emption and one that cannot. We should be looking for an alternative rather than introduce another hierarchy stemming from an abstract ShortestJobRunner class.

Composition as an alternative to inheritance

What if there was a single TaskRunner class which contained within it an object of a type say TaskAlgorithm. This member could contain whatever algorithm we choose for getting the next task. In essence this type would be an interface which will be implemented by each of the concrete algorithm implementations.

Listing: the TaskAlgorithm interface with its various implementations
 1 public interface ITaskAlgorithm {
 2   void getNextTask();
 3 }
 4 
 5 public class ShortestJobAlgorithm implements ITaskAlgorithm {
 6   void getNextTask() {
 7     //Implementation of the shortest job first algorithm
 8   }
 9   ...
10 }
11 
12 public class FirstComeFirstServeAlgorithm implements ITaskAlgorithm {
13   void getNextTask() {
14     //Implementation of first-come first-serve
15   }
16   ...
17 }

What is the volatile part of your code?

Think over what we acheived by making the ITaskAlgorithm interface and keeping the algorithms separate from the main TaskRunner class. One of the key themes of design patterns is to identify what part of your code changes often, so that we can work around this variability without a redesign of the other parts. Here are take our bunch of algorithms (or strategies to use the pattern jargon), and encapsulate them as a variable concept.

Implementing the strategy pattern

We have already created the ITaskAlgorithm interface and fleshed out some of the algorithm implementations (also known as concrete strategies). Let us now construct the single level TaskRunner class.

Listing: the TaskRunner class
 1 public class TaskRunner {
 2   ITaskAlgorithm strategy;
 3   
 4   // Setter for the algorithm
 5   public void setStrategy(ITaskAlgorithm strategy) {
 6     this.strategy = strategy;
 7   }
 8   
 9   public void nextTask () {
10     // Run the getNextTask for whatever strategy was decided
11     strategy.getNextTask();
12   }
13   ...
14 }

You can now use the strategy setter to dynamically decide which algorithm should be chosen. Since we are free to create new algorithm implementations as long as they implement ITaskAlgorithm, we have effectively coded to an interface rather than any specific implementation.

Listing: changing strategies
1 TaskRunner scheduler = new TaskRunner();
2 
3 scheduler.setStrategy(new FirstComeFirstServeAlgorithm());
4 scheduler.nextTask();
5 
6 scheduler.setStrategy(new ShortestJobAlgorithm());
7 scheduler.nextTask();

Our strategy pattern implementation migrated to Python

Let’s see if we can write a direct translation of our above implementation in Python. We will choose a simple class to serve as the replacement of our ITaskAlgorithm interface.

Listing: the interface implemented as a Python class
1 class ITaskAlgorithm:
2    def get_next_task(self):
3        raise NotImplementedError('Use a concrete strategy, this is an abstract')

Now we implement our various algorithm strategies as subclasses of ITaskAlgorithm.

Listing: our concrete strategies in Python
1 class ShortestJobAlgorithm(ITaskAlgorithm):
2     def get_next_task(self):
3         return('Running the next shortest job')
4         
5 class FirstComeFirstServeAlgorithm(ITaskAlgorithm):
6     def get_next_task(self):
7         return('Running the next job in the queue')

Our TaskRunner class and the main script can then be written in Python as:

Listing: tranlating TaskRunner and the main script to Python
 1 class TaskRunner:
 2     def __init__(self):
 3         pass
 4         
 5     def set_strategy(self, strategy):
 6         self.strategy = strategy
 7         
 8     def next_task(self):
 9         return(self.strategy.get_next_task())
10         
11         
12 if __name__ == "__main__":
13     t = TaskRunner()
14     t.set_strategy(ShortestJobAlgorithm())
15     print(t.next_task())

While we have achieved our purpose in Python too, isn’t this a long way to go about it? Can we not use Python’s features to achieve the same flexibility of the strategy pattern. After all, the way to get to a solution in Java might not be the best way to get to the same solution in Python. Turns out, there is a simpler way in Python.

 1 class TaskRunnerExample:
 2     def __init__(self, strategy=None):
 3         if strategy:
 4             self.next_task = strategy
 5             
 6     def next_task(self):
 7         print("Running default strategy")
 8         
 9         
10 def ShortestJobAlgoritm():
11     print("Running the next shortest job")
12     
13 def FirstComeFirstServeAlgorithm():
14     print("Running the next job in the queue")
15 
16 if __name__ == "__main__":
17     t = TaskRunnerExample()
18     t.next_task()
19     
20     t_sjf = TaskRunnerExample(ShortestJobAlgoritm)
21     t_sjf.next_task()
22     
23     t_fcfs = TaskRunnerExample(FirstComeFirstServeAlgorithm)
24     t_fcfs.next_task()

We have removed the concept of the top level interface completely. While we do lose adherence to a contract of sorts, I believe we gain a shorter, cleaner solution which to me is a net-win. It is possible to do this in Python because of its feature of first class functions. It means Python allows you to pass functions as arguments and even return them as values from other functions. Notice how the strategies are effectively functions that can be passed as an argument to the __init__ of the implementaion class.

Decorator Pattern

Consider a Find dialog in a text editor. While the basic find operation is pretty simple, there are some options (usually) available to do more advanced searching. We see checkboxes whether or not the search pattern is a regular expression, whether we want to search in the current file or a directory and even an option to enter the replacement text. Let us see if the decorator pattern can help us here.

Permutations and combinations

In our text editor, the Find dialog box is a class. When we decide to support regular expression searching, we write a subclass called FindWithRegEx.

Listing: the Find class hierarchy
 1 class FindDialog {
 2   public void find (String toFind) {
 3     ...
 4   }
 5   ...
 6 }
 7 
 8 class FindWithRegEx extends FindDialog {
 9   public void find (String toFind) {
10     ...
11   }
12   ...
13 }    

We can write another subclass of FindDialog which handles the replace functionality. And another to search in a directory. But what if we want to have a replace functionality with regular expressions? Do we extend FindWithRegEx or the replace class? And what happens when we start dealing with the replace functionality in a directory supporting regular expressions? The permutations and combinations start getting out of control.

Decorating the same entity

The decorator pattern is all about keeping the same entity - the FindDialog in our case - and decorating it with additional features or responsibilities at runtime. How do we go about keeping the same entity - by implementing the same interface for both the simple find dialog and all it’s decorations.

Listing: the top level interface and the simple Find dialog
 1 public interface FindDialog {
 2   public void find();
 3   public void displayHelp();
 4 }
 5 
 6 class SimpleFind implements FindDialog {
 7   public void find (String toFind) {
 8     ...
 9   }
10   
11   public void displayHelp() {
12     System.out.println("Search current file for text");
13   }
14 }

Now we start constructing our decorations. Our goal is to provide such an outline for decorations that it not only adheres to the FindDialog interface, it should also provide a barebones structure for further decorator writers. An abstract class which implements the FindDialog interface would make a good blueprint for concrete decorators. This class, being abstract, can bind decorator writers to implement certain methods which all decorators should share.

Listing: creating concrete decorators
 1 public abstract class FindDecorator implements FindDialog {
 2   protected FindDialog enhancedFind;
 3   
 4   // Constructor
 5   public FindDecorator(FindDialog findDialog) {
 6     this.enhancedFind = findDialog;
 7   }  
 8   
 9   public abstract void find();
10   
11   public void displayHelp() {
12     enhancedFind.displayHelp();
13   }
14 }
15 
16 public class FindWithRegEx extends FindDecorator {
17   
18   public FindWithRegEx(FindDialog findDialog) {
19     super(findDialog);
20   }
21   
22   public void (String toFind) {
23     ...
24   }
25   
26   public void displayHelp() {
27     super.displayHelp();
28     System.out.println("[with Perl compatible regular expressions]");
29   }

Using our decorators

We will now create a simple test program to see whether our decoration functionality is working.

Listing: testing our decorator
1 public class DecoratorExample {
2   public static void main(String[] args) {
3     FindDialog findDialog = new FindWithRegEx(new SimpleFind());
4     findDialog.displayHelp();
5   }
6 }    

The interesting line to note here is the construction of the findDialog object. This object is a SimpleFind decorated with our FindWithRegEx decorator. Both the former class and the decorator share the same parent type - the FindDialog interface. When the displayHelp method is called on this object, the FindWithRegEx methos is called which calls its super class method first and then adds its own decoration. The output then is, expectedly, both the lines.

Note that there is no limit to the number of decorations you can apply. Nor are you limited by the order you apply them, because of the super parent interface you created in the beginning.

The decorator stripped to its core

Before we look at the Python implementation of the decorator pattern, let us try to identify the true essence of the decorator pattern. The entire pattern is about providing multiple optional behaviours of a kind of object, and in doing so, the decorated object must adhere to the contract of the original object. Put another way, the caller must not know whether it is dealing with the original object or the decorated one.

Let us now try to build this in Python with minimalism in mind.

Listing: emulating the decorator pattern in Python
 1 class SimpleFind:
 2     def display_help(self):
 3         print('A simple find dialog')
 4 
 5 class FindWithRegEx:
 6     def __init__(self, findobj):
 7         self.findobj = findobj
 8 
 9     def display_help(self):
10         self.findobj.display_help()
11         print('with RegEx support')
12 
13 f = FindWithRegEx(SimpleFind())
14 f.display_help()

The above code works as expected by we are really playing freely here. Our assumption is that both the classes contain the display_help method. What if we wanted to bring some type checking into play here, ensuring at a minimum that both the classes do indeed have such a method?

Enter the Abstract Base Class of Python

We can use the module abc to define abstract base classes in Python, which would serve our need to enforce certain contracts by emulating interface-like behavior. Have a look at the code below and notice the FindDialog class being defined as an abstract base class.

Listing: using abstract base classes to implement the decorator pattern
 1 from abc import ABCMeta, abstractmethod
 2 
 3 class FindDialog(metaclass=ABCMeta):
 4     @abstractmethod
 5     def display_help(self):
 6         pass
 7         
 8 class SimpleFind(FindDialog):
 9     def display_help(self):
10         print('A simple find dialog')
11 
12 class FindWithRegEx(FindDialog):
13     def __init__(self, findobj):
14         self.findobj = findobj
15 
16     def display_help(self):
17         self.findobj.display_help()
18         print('with RegEx support')
19 
20 f = FindWithRegEx(SimpleFind())
21 
22 if not isinstance(f, FindDialog):
23     raise TypeError('Our creation is not a find dialog')
24 else:
25     f.display_help()

Since we have defined FindDialog as an abstract class containing an astract method display_help(), we cannot instantiate the class itself. Writing something like below will throw up an error.

1 t = FindDialog()
2 
3 >Traceback (most recent call last):
4   File "Code/python/decorator.py", line 21, in <module>
5     t = FindDialog()
6 TypeError: Can't instantiate abstract class FindDialog with abstract methods dis\
7 play_help

We can see how we have implemented our contract and applied our decorators to the final object f. If our decorator was not a subclass of FindDialog we would have gotten a runtime TypeError which we raised. If our decorator was a subclass of FindDialog but did not implement the abstract method display_help(), we would have gotten another error.

Factory Pattern

The Limitations of Object Construction

Creation of objects using plain old constructors and the new operator is fairly constricting in many situations. Suppose you are creating an information management application which supports different note types - plain note, rich note, outline note etc. If all these notes extend from a super class Note, using new on this super class cannot return its subtype note i.e. it cannot return a specific type of note we desire.

So while you can do,

Note n = new Note();

Note m = new RichNote();

You cannot perform something like:

RichNote n = new Note("Rich");

A constructor invoked through new cannot specify a return type at all, let alone a different return type. Clearly our need to create different but related object types cannot be solved by constructors in an elegant manner.

Enter the Simple Factory

What if we had a method which could return objects like a constructor but not suffer from its limitations? We know somewhere down the line we have to make a call to it using new, but can we give a uniform cover of sorts to this problem of related note types. This is where we encounter a factory, which is a plain old class containing a method returning our desired subtype note.

Listing: a simple factory
 1 public class NoteFactory {
 2   private String type;
 3   
 4   // Constructor of our factory
 5   public NoteFactory(String t) {
 6     type = t;
 7   }
 8   
 9   public Note createNote() {
10     if (type.equals("Rich")) {
11       return new RichNote();
12     }
13     else if (type.equals("Outline")) {
14       return new OutlineNote();
15     }
16     . . .
17   }  
18 }  

The createNote() method serves as our object creator, returning the note type we desire. This is possible because the method returns a type Note which would serve as an ancestor to all the different note types. Since it is evident that it does not make sense to create instances of Note (what kind of note is a clearer alternative), we can go ahead and make it an abstract class.

Listing: the Note hierarchy
 1 public abstract class Note {
 2   . . .
 3 }
 4 
 5 public class RichNote extends Note {
 6   . . .
 7 }
 8 
 9 public class RichNote extends Note {
10   . . .
11 }

Factory Method

The original Gang of Four book did not define the Factory pattern as shown above. Which is why programmers differentiate the two by calling what we implemented in the previous section as a Simple Factory and the GoF way as the Factory Method pattern.

The primary difference between them is that in the latter, we specify our factory as an abstract class. It is then left for realization by other implementers who have to make concrete factories based upon your original blueprint. This brings in another dimension of flexibility to the creation of objects using factories.

Software, as evidenced by modern trends, tends to suffer from featuritis - adding a slew of features in every release. And alas, our simple note taking application has also fallen prey to this. The powers that be want to see it support multimedia notes which are treated very differently than textual notes. Besides the fact that they are created and have a title, they share little else with our previous note styles. The Factory Method pattern can help us out here.

Listing: the Factory Method pattern
 1 public abstract class NoteFactory {
 2   String title;
 3   public abstract Note createNote();
 4   . . .
 5 }
 6 
 7 public class TextNoteFactory extends NoteFactory {
 8   // Concrete factory for creating TextNotes (Rich, Outline, Plain etc.)
 9   . . .
10 }
11 
12 public class MultimediaNoteFactory extends NoteFactory {
13   // Concrete factory for creating multimedia notes (videos, audio recordings)
14   . . .
15 }

The various note types can now extend Note and yet be created by a specialized form of NoteFactory. As time goes on, and yet newer demands are made on the categories of notes supported, we can create newer specializations of NoteFactory.

Implementing the simple factory in Python

A simple translation of the factory to Python is straightforward. We will attempt this line by line picking up the inspiration from our Java implementation.

Listing: a simple factory implementation in Python
 1 class Note:
 2     pass
 3 
 4 
 5 class RichNote(Note):
 6     def __init__(self):
 7          print("A rich note")
 8 
 9 
10 class SimpleNote(Note):
11     def __init__(self):
12          print("A simple note")
13 
14 
15 class NoteFactory():
16     def __init__(self, type):
17         self.type = type
18     
19     def create_note(self):
20         if self.type == 'Rich':
21             return RichNote()
22         else:
23             return SimpleNote()
24 
25 
26 if __name__ == '__main__':
27     nf = NoteFactory('Plain')
28     nf.create_note()

Pretty simple, huh? No surprises waiting for us; perhaps not the most elegant way to go about designing your Python codebase but that is another matter. What if we go back and revisit our assumption that the object construction process cannot return a different type. Does Python allow something like this? Well, we don’t really have a formal constructor but the object creation does involve calling the __init__ function. Let us try specifying a return type there - have a look at the code below.

Listing: trying to make init return a different type
 1 class Note:
 2     pass
 3 
 4 
 5 class RichNote(Note):
 6     pass
 7 
 8 
 9 class SimpleNote(Note):
10     pass
11 
12 
13 class NoteFactory():
14     def __init__(self, type):
15         self.type = type
16         if type == 'Rich':
17             return RichNote()
18         else:
19             return  SimpleNote()
20 
21 
22 if __name__ == '__main__':
23     NoteFactory('Normal')

If we attempt to run this, Python throws back an error, a TypeError to be precise.

1 TypeError: __init__() should return None, not 'SimpleNote'

Clearly this is not the way to go about things. Wading through the Python documentation, we come across a similar method called __new__. This allows us to return some other class’ object. Let’s try this method in our code sample.

Using new to return a different type
 1 class Note:
 2     pass
 3 
 4 
 5 class RichNote(Note):
 6     def __init__(self):
 7         print("A rich note")
 8 
 9 
10 class SimpleNote(Note):
11     def __init__(self):
12         print("A simple note")
13     pass
14 
15 
16 class NoteFactory():
17     def __init__(self):
18         pass
19 
20     def __new__(self, type):
21         if type == 'Rich':
22             return RichNote()
23         else:
24             return  SimpleNote()
25 
26 
27 if __name__ == '__main__':
28     nf = NoteFactory('Rich')
29     print(nf)
1 => A rich note
2 <__main__.RichNote object at 0x1019749b0> 

Well, this looks promising. The nf object turned out to be of type RichNote, completing our note factory concept.

Observer Pattern

The formal definition of the pattern is to define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

The purpose of the observer pattern is to allow the originator of an event to notify its observer(s) without the latter needing to continously perform any polling mechanism. Consider the analogy of Twitter - a person tweets i.e. generates an event, and his or her followers get notified of the said tweet. The followers can be thought of as observers of the tweet generation event.

Where does the Observer pattern fit?

Whenever you think of a subscription like system, consider whether your design can make use of the observer pattern. A blog engine for example, would let fellow bloggers follow another. Whenever the blogger in question posts an entry, the very act of publishing can trigger notifications to his/her subscribers.

We are not limited to the concept of subscription in the context of people. Imagine a very sensitive table in a database. Certain systems need to be notified whenever there is a new entry in the table - like a ledger entry needs to notify compliance systems etc. in the finance world. This can also be a scenario where the observer pattern may come in handy.

Implementing the Observer pattern in Python

For our Python implementation we are going to use the blog entry subscription example. A user would register (initialize) a blog and subsequently add posts to it. Readers can subscribe to the blog and get notified whever the author puts up a new post.

Take careful note of the methods in the two classes described below. The Blog class has methods to add new subscribers, add new posts and notify the subscribers when a new post is added. What is clearly missing here is the ability to remove a user subscription. However, that is a matter of simply modifying the self.subscribers list and is left out for brevity. It adds little to our purpose of seeing the observer pattern in action.

Listing: the observer pattern in Python
 1 class Blog:
 2     def __init__(self, name):
 3         self.subscribers = []
 4         self.posts = []
 5         self.author = name
 6         
 7     def subscribe(self, subscriber):
 8         self.subscribers.append(subscriber)
 9         
10     def notify_subscribers(self):
11         for reader in self.subscribers:
12             reader()
13     
14     def add_post(self, post):
15         self.posts.append(post)
16         print(self.author + ' added a post')
17         self.notify_subscribers()
18 
19         
20 class Reader:
21     def __init__(self, reader_name):
22         self.reader = reader_name
23         
24     def __call__(self):
25         print(self.reader + " was notified")
26         
27         
28         
29 originator = Blog('Kirsten')
30 
31 subscriber_1 = Reader('Ole-Johan')
32 subscriber_2 = Reader('Robert')
33 
34 originator.subscribe(subscriber_1)
35 originator.subscribe(subscriber_2)
36 originator.add_post("Representing complex systems as computer simulations")

The heart of the pattern lies in the notify_subscribers call and definition. The method goes over the list of subscribers and calls them as functions, even though we know that these are Reader objects1.

Now note the methods of the Reader class. Besides the usual __init__, we have __call__ which is a special method that gets invoked automatically when an object instance is treated like a function and called. Essentially, if o is an instance and it is called like o(params), it will be treated like o.__call__(params). This feature offered by Python makes our implementation particularly clean and easy to understand.

Java’s take on the Observer

If you read the Python implementation carefully, you would notice that except for the notify_subscribers method and the language specific __call__, there is not much to the code that cannot be directly translated to Java. And we can easily get around the aforementioned contructs by asking all observers to adhere to an interface.

Listing: implementing the Observer contract in Java
 1 public interface Observer {
 2     public void update();
 3 }
 4 
 5 public class Reader implements Observer {
 6     public void update() {
 7         . . .
 8     }
 9 }
10 
11 // The homepage should also be updated
12 public class Homepage implements Observer {
13     public void update() {
14         . . .
15     }
16 }

Notice how we added another observer class - Homepage adhering to the same contract. The idea being once the writer pens a new entry, the homepage should get notified and updated too.

The built-in Observer implementation in Java

Ever since Java came out in the mid-90s, it has shipped with an Observable class and an Observer interface. While there are many finer points of using these, I’d best leave that to the Java standard library documentation. But here are some of the highlights to help you get started.

Notice I mentioned the Observable class - to build your own subjects (the objects to be observed), you need to create a subclass of it. If you are a Java programmer you would notice that this means your subject class cannot extend any other superclass since Java will not allow you to have multiple parent classes. The Observer is mercifully a standard interface which leaves you to implement your own update() method.

Listing: built in support for making observers in Java
 1 import java.util.Observable;
 2 import java.util.Observer;
 3 
 4 public class Blog extends Observable {
 5     public void publishEntry(Entry e) {
 6         . . .
 7         setChanged();
 8         notifyObservers();
 9     }
10 }
11 
12 public class Reader implements Observer {
13     public Reader(Observable observable) {
14         this.observable = observable;
15         observable.addObserver(this);
16     }
17     public void update() {
18         . . .
19     }
20 }

Extending the Observable class gives you a lot of pre-built functionality. You already get methods like addObserver(), deleteObserver() and notifyObservers() which takes away the pain of manually writing observer management. Whether you wish to use this of roll your own Observer pattern implementation is your call.

  1. Well, we hope these are Reader objects. Python will not complain if you put another type of object in there. Viva la dynamic typing!

Template Method Pattern

The template method pattern is one of those patterns that seem so obvious that many question whether it should indeed be called a pattern at all. If you know what inheritance and abstract classes and methods are and what they are used for, you pretty much know about the template method pattern.

It is, however, a part of the original Gang of Four patterns and you don’t want to be looking clueless when somebody starts talking about finalizing a template method. Another reason to study it would be to understand where the pattern should not be fitted. So let’s begin by finding a situation to put this pattern to use.

T’was a time of email clients

Long before checking emails through a web browser became all the rage, you had to install a mail client on your computer and go from there. And if you happen to be programming one, a big hurdle for you would be getting the mail composition bit right. You see email comes in two flavors - plaintext and HTML, and creating them requires different invisible headers which are important if you are creating an email client.

What is the process of sending an email? For our illustrative purposes only, let’s suppose it is as below.

  1. Get text of the email (and optional formatting) from wherever the user has entered it
  2. Apply headers for supporting formatting
  3. Fill out the correct address fields (To:, CC:, BCC:)
  4. Retrieve login credentials and authenticate with the SMTP server
  5. Send the mail through SMTP

In this recipe of 5 steps, only step number 2 is different for sending our different email formats. The rest of the steps pretty much remain the same. The header field Content-Type for plaintext emails is text/plain whereas it is text/html for HTML formatted mails.

The template method in Java

Let us suppose we are making our very own mail sending program, and that too in Java. We stick to our tried and trusted object oriented design methodology and make a Mail class which is the parent class of PlainTextMail and HTMLMail. Each of the steps in our mail sending process becomes a method of the mailing classes.

Listing: a basic OO design of a mail sender
 1 public abstract class Mail {
 2     void getText (InputSource source) {
 3     }
 4 
 5     abstract void applyHeaders();
 6 
 7     void fillAddressFields (Fields fields) {
 8     }
 9 
10     void authSMTP (String user, String password, String method) {
11     }
12 
13     void sendMailUsingSMTP (SMTPConnection conn) {
14     }
15 }
16 
17 public class PlainTextMail extends Mail {
18     void applyHeaders() {
19         this.contentTypeHeader = 'text/plain';
20     }
21 }
22 
23 public class HTMLMail extends Mail {
24     void applyHeaders() {
25         this.contentTypeHeader = 'text/html';
26     }
27 }

Nothing too unexpected there. The abstract class defines and implements most of the methods and the concrete classes simply overrides the method which is specialized, saving us a ton of duplicate code. Now we piece together another method which chains the above methods up in sequence so that we can wrap the mail sending process in a single step.

Listing: the template method
1 void sendMail() {
2     getText();
3     applyHeaders();
4     fillAddressFields();
5     authSMTP();
6     sendMailUsingSMTP();
7 }

And where should we put in this method - the abstract class, of course. The steps for sending the mail remain the same no matter what is the content of the mail. We have just implemented our template method, which fixes the steps for an algorithm or procedure. If we declare this method as final, we ensure that nobody can modify the mail sending procedure.

Hooks

What if a particular step of the algorithm can be implemented differently or even kept optional in the concrete implementations? To cater to this need, we use hooks which are given a default implementation in the base class but the subclasses are free to override it. Let’s see if we can take one of our methods and make it a hook.

One of the least well-known features of email is the Reply-To field. The email format has provisions that when you hit reply to a mail, it can go to a different email address than the one that sent the mail. Let’s suppose that we want out rich interface email composer (the one that makes HTML emails) to have the option to set this field.

If the abstract class Mail sets the value of the field same as the from field, it provides a nice default implementation. We will hook on a new implementation of it in the HTMLMail class so that we can set a different address.

Listing: using hooks
 1 public class HTMLMail extends Mail {
 2     void applyHeaders() {
 3         this.contentTypeHeader = 'text/html';
 4     }
 5     
 6     void fillAddressFields(Fields fields) {
 7         // Other field settings
 8         // . . .
 9         
10         this.replyTo = fields.getReplyToValue();
11     }
12 }

The template method in Python

Porting our template method logic to Python is fairly straightforward. To keep things really simple and minimal, let’s look at a barebones implementation of the concept.

Listing: the Mail base class in Python
 1 class Mail:
 2     def get_text(self, source):
 3         . . .
 4 
 5     def apply_headers(self):
 6         raise NotImplementedError()
 7 
 8     def fill_address_fields(self, fields):
 9         . . .
10 
11     def auth_SMTP(self, user, password, method):
12         . . .
13 
14     def send_mail_using_SMTP(self, conn):
15         . . .
16     
17     # Our template method
18     def send_mail():
19         self.get_text()
20         self.apply_headers()
21         self.fill_address_fields()
22         self.auth_SMTP()
23         self.send_mail_using_SMTP()

Note how we have written the abstract method by simply raising an exception. This forces the implementor to write a concrete apply_headers() in the derived classes.

Listing: our concrete implementations of the Mail subclasses
1 class PlainTextMail(Mail):
2     def apply_headers(self):
3         . . .
4 
5 
6 class HTMLMail(Mail):
7     def apply_headers(self):
8         . . .

While this is a nice, simple and clean implementation - it does suffer from a tiny flaw. We can instatiate Mail when we really don’t want to give the option to create a Mail object with an undefined format. So we take the help of our trusted Abstract Base Class of Python and specify apply_headers() as an abstract method.

Listing: specifying Mail as an abstract class
 1 from abc import ABCMeta, abstractmethod
 2 
 3 class Mail(metaclass=ABCMeta):
 4     
 5     @abstractmethod
 6     def apply_headers(self):
 7         raise NotImplementedError()
 8 
 9     # Rest of the method implementations
10     # . . .
11    
12     # Our template method
13     def send_mail():
14         self.get_text()
15         self.apply_headers()
16         self.fill_address_fields()
17         self.auth_SMTP()
18         self.send_mail_using_SMTP()

Singleton Pattern

Much has been said and written about the singleton pattern. Some good and some not so complimentary. While we will discuss the reason behind the criticism the pattern has drawn in recent years, let us first focus on understanding the pattern itself.

A singleton refers to a class which can be instantiated once and only once. Every time we demand a new instance of the class, it returns the same object. Right off the bat, we can probably see where such an object instantiation strategy might come in handy - database connections, logging etc.

Implementing singletons in Java

To control how many instances of a particular class can be created, it is obvious that we would have to tinker around with the process of object creation and its primary player - the contructor. The constructor will always return a new object when it is auto invoked using new, and so we must write find means to hide it.

This hiding of the constructor can be achieved by the judicious use of access modifiers - marking the constructor as private. This is reasonably simple, but we must provide another way to get an instance. Also we must control the number of instances that can be created from this instantiation method.

Listing: restricting access to the constructor
1 public class DatabaseConnection {
2     
3     // The restricted constructor 
4     private DatabaseConnection();
5 
6     public DatabaseConnection getDBConnection() {
7         . . .
8     }
9 }

We just introduced our getDBConnection method which will serve in place of the constructor to get new DatabaseConnection objects. Here we must apply the logic to instantiate the class once and return the same instantiation on repeated calls. Another thing that we have to bear in mind that the getDBConnection method must be a static method. It must be callable without an instance of its class, since its very purpose is to return an instance.

Listing: implementing a singleton in Java
 1 public class DatabaseConnection {
 2     
 3     // A unique instance
 4     private static DatabaseConnection dbConn;
 5 
 6     // The restricted constructor 
 7     private DatabaseConnection();
 8 
 9     public static DatabaseConnection getDBConnection() {
10         if (dbConn == null) {
11             dbConn = new DatabaseConnection();
12         }
13         return dbConn;
14     }
15 }

We use a static variable to hold the unique instance of our class. Thus before we create an instance, we check whether we already have another one and if so, return that. For simple scenario’s, these steps ensure that you will get one and only one instance of the database connection.

Complications in a multi-threaded environment

Dealing with multithreaded code is challenging, but even more so when we introduce singletons in the mix. Consider what would happen if there were two threads operating on the getDBConnection() method.

There may arise a situation where thread 1 has performed the dbConn == null check and proceeded to start the object creation process. At this very moment, thread 2 could be checking the condition also and did not find the instantiated dbConn object because thread 1 has not finished object creation. Thus thread 2 would also start its call to the constructor breaking our singleton pattern implementation.

Java provides us with the synchronized keyword - a way to ensure thread safety. By simply adding this in the declaration of getDBConnection() we ensure that no two threads can execute this method at the same time.

1 public static synchronized DatabaseConnection getDBConnection() {
2     . . .
3 }

The trouble with this simple fix is performance. Consider the fact that our complicated multithreading issue only arises if both threads try for a concurrent getDBConnection before anything else has created a unique instance. If there already existed a dbConn object, it would not matter how many threads tried to run getDBConnection at the same time. But our fix added the performance penalty of using the synchronized feature every time a database connection is requested.

Another simple fix is to eagerly create a singleton instance and let getDBConnection() always return it.

Listing: an eagerly created singleton
 1 public class DatabaseConnection {
 2     
 3     // A unique instance
 4     private static DatabaseConnection dbConn = new DatabaseConnection();
 5 
 6     // The restricted constructor 
 7     private DatabaseConnection();
 8 
 9     public static DatabaseConnection getDBConnection() {
10         return dbConn;
11     }
12 }

While this approach is also pretty elegant in its simplicity, it also means that you will always have an instance of DatabaseConnection. The instance will be eagerly created at class load time, whether or not someone calls getDBConnection().

Implementing singletons in Python

The Python community is not very dogmatic when it comes to implementing design patterns. In fact, many Pythonistas believe that the study and implementation of design patterns is better suited to languages like Java and C++ and should be used in Python sparingly.

The pythonic way to implement a singleton in Python is to simply mimic it using a module level variable. Any variable defined in the main body of a module, be it a simple variable or an object instantiation, will be executed exactly once at import time. Though there is nothing that stops the importer from reassigning the (singleton) variable to something else entirely, the Python community takes the view that we are all consenting adults here. If someone wishes to reassign the variable, let them. Can’t say I disagree with this pragmatic approach.

Let’s implement this as simply as possible. We create our DBConnection class as below and instantiate it in the same module.

Listing: creating our database connection module
1 class DBConnection:
2     def __init__(self):
3         print('Class instantiated')
4 
5 
6 dbconn = DBConnection()

Effectively dbconn has become a module level variable and thus a singleton for our purpose. Let us import this into our script.

Listing: importing our singleton
1 import database_connection
2 
3 print('Process something')

The class is instantiated and assigned to dbconn the moment our script processes the import statement in the very first line. Thus our output is in the sequence given below.

1 Class instantiated
2 Process something

Other than this simple but useful technique, there are some other tangential ways to mimic singletons in Python. You have to fiddle with the __new__() method but I don’t particularly recommend it. There is also a related pattern called Borg which serves almost the same purpose as a singleton by implementing shared state.

The problem with Singletons

If you really think about singletons, we essentially use them as global state holding variables which are shared across the application instance. Whenever you see the word global variable or shared state, take a good hard look at whether you do need a design which promotes these. In a lot of cases, instead of rigid rules of instance creation, we should trust the programmers using our code to do the right thing. While this does seem scary at first, more often than not, we overemphasize singletons.

Consider database connections - while it is not a great idea to flood the database server with incoming connection requests, it is equally bad to let a glitch in one part of the code affect another. What happens when say a part of code locks up the database with a long running transaction? Should everyone else wait their turn since we can only have a single database connection?

Another principle that singletons violate is single responsibility. Instead of just being good at their own purpose, they also minutely cover their own creation. So now they have to be good at two things, one more than the ideal situation. All in all, there may be cases you’d want to use singletons, just be sure you really need them.

Further Reading

Design patterns is a vast subject. Knowing them and using them is important, as is knowing when not to use them. Below are some of the texts I recommend to futher your knowledge of design patterns.

  1. Head First Design Patterns by Eric Freeman, Bert Bates, Kathy Sierra and Elisabeth Robson (1st Edition, 2004)

    Visual, easy and solid introduction to the world of design patterns. If you use Java, this is a must have.

  2. Python 3 Object Oriented Programming by Dusty Phillips (1st Edition, 2010)

    My favorite book on design patterns explanation in Python. Readable and to the point.

  3. Design Patterns Explained: A New Perspective on Object Oriented Design by Alan Shalloway and James R. Trott (2nd Edition, 2004)

    A formal introduction to design patterns using Java examples. Thorough but a bit dry.

  4. Design Patterns: Elements of Reusable Object-Oriented Software by Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides (1st Edition, 194)

    The GoF book that start it all. While a classic, I don’t prefer reading this straight up. Examples are in C++.