Behavioral Design Patterns


The Creational and Structural patterns help us create objects and establish static relationships between them. But, the dynamic behavior - how they interact with each other in a working system is defined by the Behavioral pattern that we use. They identify common communication patterns between objects - this increase the flexibility in communication between objects.

Chain of Responsibility


A typical IT company has developers, testers, managers, sales and marketing teams and various different departments. These roles often overlap in small companies (<100 employees), but in some of the bigger ones, each of these have an elaborate hierarchy, and very few employees know each other. Yet, the process is (should be) set up in a way that everyone gets to do his job and contribute appropriately to the extent that the final product is delivered with quality and schedule.

How does the information travel across the organization? Each employee of the organization cannot start broadcasting all that he has to say - that would cause chaos. All the information cannot be shared with everyone in the organization - that would cause chaos too. The right way to do this, is by defining an appropriate process and defining roles that can pass the information to each other till it reaches everyone concerned.

That is a chain of responsibility. In a complex software application, it is not possible (or advisable) to have each module talking to the other. A well designed system should keep them isolated. In such a case, passing information can be a big challenge. The chain of responsibility pattern is the ideal solution to such a problem. A module can pass on the information to the connected module that is responsible for passing it ahead, and so on till it reaches the destination.

In this way, the information is passed without the source or target knowing each other. But the chain must be directed. Each object should know the direction in which it should pass a given message - else it would be worse than a broadcast.

This avoids attaching the sender of a request to its receiver, giving this way other objects the possibility of handling the request too. The objects become parts of a chain and the request is sent from one object to another across the chain until one of the objects will handle it.

The participants in a chain of responsibility are:

  • Client - The source of the message
  • Handler - An interface that exports a method handleMessage(). Each component of the chain of responsibility implements this interface and allows the request to pass along.
  • Concrete Handler - This is the actual recipient of the message that accepts the request and processes it.

Let us now look at how the Chain of Responsibility pattern in implemented in code:

public class Request {	
	private int m_value;
	private String m_description;

	public Request(String description, int value) {
		m_description = description;
		m_value = value;
	}

	public int getValue() {
		return m_value;
	}

	public String getDescription() {
		return m_description;
	}          
}

public abstract class Handler {
	protected Handler m_successor;
	public void setSuccessor(Handler successor) {
		m_successor = successor;
	}

	public abstract void handleRequest(Request request);
}

public class ConcreteHandlerOne extends Handler {
	public void handleRequest(Request request) {
		if (request.getValue() < 0) {           //if request is eligible handle it
			System.out.println("Negative values are handled by ConcreteHandlerOne:");
			System.out.println("\tConcreteHandlerOne.HandleRequest : " + request.getDescription()
						 + request.getValue());
		} else {
			super.handleRequest(request);
		}
	}
}

public class ConcreteHandlerThree extends Handler {
	public void handleRequest(Request request) {
		if (request.getValue() >= 0) {           //if request is eligible handle it
			System.out.println("Zero values are handled by ConcreteHandlerThree:");
			System.out.println("\tConcreteHandlerThree.HandleRequest : " + request.getDescription()
						 + request.getValue());
		} else {
			super.handleRequest(request);
		}
	}
}

public class ConcreteHandlerTwo extends Handler {
	public void handleRequest(Request request) {
		if (request.getValue() > 0) {           //if request is eligible handle it
			System.out.println("Positive values are handled by ConcreteHandlerTwo:");
			System.out.println("\tConcreteHandlerTwo.HandleRequest : " + request.getDescription()
						 + request.getValue());
		} else {
			super.handleRequest(request);
		}
	}
}

public class Main {
	public static void main(String[] args) {
		// Setup Chain of Responsibility
		Handler h1 = new ConcreteHandlerOne();
		Handler h2 = new ConcreteHandlerTwo();
		Handler h3 = new ConcreteHandlerThree();
		h1.setSuccessor(h2);
		h2.setSuccessor(h3);

		// Send requests to the chain
		h1.handleRequest(new Request("Negative Value ", -1));
		h1.handleRequest(new Request("Negative Value ",  0));
		h1.handleRequest(new Request("Negative Value ",  1));
		h1.handleRequest(new Request("Negative Value ",  2));
		h1.handleRequest(new Request("Negative Value ", -5));	    
	}
}

Command Pattern


We have all visited doctors at some point in our life. After due checkup, the doctor diagnosed the disease and prescribed some pills that we obtained from the pharmacy. The pharmacist hands over the pills that we need - his job ends there. The way we consume the pills barely depends upon what they contain - we just gulp them down with a glass of water - this process remains unchanged irrespective of what those pills contain. Everything works if the prescription was good.

This is command pattern. It decouples an object that invokes the operation from the one that actually performs it. Thus, we have two modules - one that knows how the command should be invoked and other that knows how it should be implemented. The command pattern ensures a good decoupling between the two.

This is achieved by defining a Command interface with an execute() method taking relevant parameters (the medical pill in our case). A concrete implementation of this Command interface is instantiated by the client (the pharmacist) and handed over to the Invoker (the patient) - that actually triggers the execute method when prescribed. This works well if the designer (the doctor) has coordinated things correctly.

All clients of Command objects treat it as a "black box" by simply invoking the object’s virtual execute() method whenever the client requires the object's "service". A Command class holds some subset of the following: an object, a method to be applied to the object, and the arguments to be passed when the method is applied. The Command's "execute" method then causes the pieces to come together.

Sequences of Command objects can be assembled into composite (or macro) commands.

Thus, the participants in the command pattern are:

  • Command - Declares an interface for executing an operation.
  • ConcreteCommand - Defines a binding between a Receiver object and an action. Implements Execute by invoking the corresponding operation(s) on Receiver.
  • Client - Creates a ConcreteCommand object and sets its receiver.
  • Invoker - Asks the command to carry out the request.
  • Receiver - Knows how to perform the operations associated with carrying out a request. Any class may serve as a Receiver.

Interpreter Pattern


In real life, an interpreter is one who translates one language into another. On similar lines, the interpreter pattern is useful when we have data in another language - perhaps an XML/JSON or some incoming data or just a regular expression - that we have to use in our code. Here, we need to convert a complex text or byte sequence into useful logic.

The interpreter pattern is very rarely used - because most interpreters are already implemented. But it is worthwhile understanding it in detail.

Any language is state based. A new piece of incoming data is meaningful in the context of what had come before it. And we cannot conclude we have understood it until we have absorbed the whole of it - since potentially, the last chunk can negate all that we got before it.

Thus, the interpreter has a Context that is built up by the incoming Expressions and this is built until it encounters the Terminal Expression that announces that there is no more data to be consumed.

The Interpreter pattern is used exhaustively to define grammars, tokenize input and store it. It can be used in rules engines. We can also use the Interpreter pattern to add functionality to the composite pattern.

The Interpreter pattern has 5 players:

  • AbstractExpression - Declares an abstract Interpret operation that is common to all nodes in the abstract syntax tree.
  • TerminalExpression - Implements an Interpret operation associated with terminal symbols in the grammar. An instance is required for every terminal symbol in a sentence.
  • NonterminalExpression - (AlternationExpression, RepetitionExpression, SequenceExpressions) - One such class is required for every rule R ::= R1 R2 ... Rn in the grammar. Maintains instance variables of type AbstractExpression - for each of the symbols R1 through Rn. Implements an Interpret operation for nonterminal symbols in the grammar. Interpret typically calls itself recursively on the variables representing R1 through Rn.
  • Context - Contains information that's global to the interpreter.
  • Client - Builds (or is given) an abstract syntax tree representing a particular sentence in the language that the grammar defines. The abstract syntax tree is assembled from instances of the NonterminalExpression and TerminalExpression classes. Invokes the Interpret operation.

Iterator Pattern


Any meaningful application deals with a chunk of data. The data is often in form of a collection of related data elements. We often need to work on each of these elements. The iterator pattern helps us do this.

This problem is not so very pronounced when we are working with Lists - because they can be indexed. We can simply access each element of the list using its index

for (int i=0; i<list.size(); i++)
    list.get(i).trigger();

But, when we work on sets or maps, it is not possible to index them directly. The Iterator Pattern helps us in such a case.

Essentially, the collection defines an "Iterator" - an object that can dish out individual element in the collection - one at a time. Anyone who needs to access each of these elements, can just invoke the iterator object.

The Iterator pattern works through these players

  • Iterator Interface: This interface defines two methods hasNext() and next(). The first method tells us if the iterator has more than it has already given. The next() dishes out the next element in it.
  • Concrete Iterator: This provides an actual implementation for the above methods. Note that the iterator does not maintain a copy of the source collection. It just provides a way to access the contents of the collection.
  • Aggregate Interface: Defines the method to createInterface(). This should return an instance of the iterator
  • Concrete Aggregate: This implements the createInterface() method.
Iterator iterator = list.createIterator();

while (iterator.hasNext()) {
    iterator.next().trigger();
}

Mediator Pattern


Mediator design pattern is one of the important and widely used behavioral design pattern. It enables decoupling of objects by introducing a layer in between so that the interaction between objects happen via the glue layer.

If the objects interact with each other directly, the system components are tightly-coupled with each other - and that increases maintenance cost. Mediator pattern focuses on providing a mediator between objects for communication and help in implementing lose-coupling between objects.

  • Mediator: It defines the interface for communication between colleague objects.
  • ConcreteMediator: It implements the mediator interface and coordinates communication between colleague objects.
  • Colleague: It defines the interface for communication with other colleagues
  • ConcreteColleague: It implements the colleague interface and communicates with other colleagues through its mediator

It limits subclassing. A mediator localizes behavior that otherwise would be distributed among several objects. Changing this behaviour requires subclassing Mediator only, Colleague classes can be reused as is. But, at the same time, It centralizes control. The mediator pattern trades complexity of interaction for complexity in the mediator. Because a mediator encapsulates protocols, it can become more complex than any individual colleague. This can make the mediator itself a monolith that’s hard to maintain

Memento Pattern


Everyone has used the undo button. Life would have been impossible without it! Memento pattern provides something similar. It is used to restore state of an object to a previous state. As your application is progressing, you may want to save checkpoints in your application and restore back to those checkpoints later. Memento pattern provides for just this.

The memento pattern consists of these participants

  • Originator : the object for which the state is to be saved. It creates the memento and uses it in future to undo.
  • Memento : the object that is going to maintain the state of originator. It's just a POJO.
  • Caretaker : the object that keeps track of multiple memento. Like maintaining savepoints.

Here is an example implementation of the memento pattern

package net.thewiz.memento;

import java.util.List; 
import java.util.ArrayList; 

class Memory { 
	private String time; 

	public void set(String time) { 
		System.out.println("Setting time to " + time); 
		this.time = time; 
	} 

	public Memento saveToMemento() { 
		System.out.println("Saving time to Memento"); 
		return new Memento(time); 
	} 

	public void restoreFromMemento(Memento memento) { 
		time = memento.getSavedTime(); 
		System.out.println("Time restored from Memento: " + time); 
	} 
}

public static class Memento { 
	private final String time; 
	public Memento(String timeToSave) { 
		time = timeToSave; 
	} 

	public String getSavedTime() { 
		return time; 
	} 
} 

class Main { 
	public static void main(String[] args) { 
		List savedTimes = new ArrayList(); 
		Memory m = new Memory(); 

		//time travel and record the eras 
		m.set("1000 B.C."); 
		savedTimes.add(m.saveToMemento()); 
		m.set("1000 A.D."); 
		savedTimes.add(m.saveToMemento()); 
		m.set("2000 A.D."); 
		savedTimes.add(m.saveToMemento()); 
		m.set("4000 A.D."); 

		m.restoreFromMemento(savedTimes.get(0)); 
	} 
}

One problem is the tight coupling between the object and its memento class. We can use Serialization to achieve memento pattern implementation that is more generic.

Observer Pattern


Consider a situation where we have an object that depends upon some event from another object. We can have several ways of implementing this relationship. Two of the most popular approaches are polling based and event based. Polling based approach works best when one object depends upon many others. Even based works better when we have many objects that depend upon one source.

The observer pattern is a more formalized form of the event based, publish-subscribe relationship between objects.

The Observer Pattern has four main participants

  • Subject: The interface or abstract class defining the operations for attaching and de-attaching observers to the subject.
  • ConcreteSubject: The concrete Subject class. It maintain the state of the object and when a change in the state occurs it notifies the attached Observers.
  • Observer: The interface or abstract class defining the operations to be used to notify this object.
  • ConcreteObserver: The concrete Observer implementations.

State Pattern


The State pattern is used when the behavior of an Object changes based on its internal state.

A simplistic way of doing this would be to have the state stored in private property, and run a chain of if-else blocks on this state, to define the behavior. Such an approach may be good when the state based variation is minimal. But, it can soon go out of control as the size of your application increases.

The State Pattern provides an elegant solution. It provide a systematic and lose-coupled way to achieve this through Context and State implementations.

Essentially, it is based upon an object instance of each state - that defines the behavior. Thus, the behavior is assigned to the owner - along with the state.

  • Context: Defines an interface to client to interact. It maintains references to concrete state object which may be used to define current state of object.
  • State: Defines interface for declaring what each concrete state should do.
  • ConcreteState: Provides implementation for methods defined in State.

In the State design pattern, an object's behavior is changed at runtime - depending on the state. This removes the dependency on the if/else or switch/case conditional logic. The State design pattern also improves Cohesion since state-specific behaviors are aggregated into the ConcreteState classes, which are placed in one location in the code.

However, if it is not used judiciously, the state pattern can bump up the number of classes in your application - making it difficult to maintain.

Strategy Pattern


The strategy pattern helps extract a particular behavior out of a class. Consider for example, an application that works with several customers. We have three types of customers - standard, executive and premium. Thus, we have three subclasses of the class Customer. Also, the customers belong to several different countries. Each country has its own specifications about the transactions. How can we create a class hierarchy out of this?

If we subclass the three customer types, based on the country, we would be repeating a lot of code among them - because each country would have three classes giving the same implementation. The problem will not be solved if we do it the other way. If we first subclass based on the country and then the category, we will have a huge duplication once again.

The problem here is that different instances of any of the three Customer classes, have a different behavior based on the country. The strategy pattern helps us here, by extracting the required behavior out of the class. We can then assign it to the instance - as required.

The strategy pattern has three distincts participants.

  • Context: Defines an interface to client to interact. It maintains references to concrete strategy object.
  • Strategy: Defines interface for declaring what each concrete strategy should do.
  • ConcreteStrategy: Provides implementation for methods defined in Strategy.

The Strategy pattern is similar to the State Pattern - in its implementation. However, there are conceptual differences. State pattern talks about a single instance of the class that changes its behavior based on the state. However, Strategy pattern talks about statically assigning a behavior to the instance.

The State pattern allows some coupling between the state and the context. The method names and parameters and return types can be defined by the state interface and the context. But the strategy pattern is based on a simple execute() method.

Template Method


Java and most OO languages allow a child class to override individual methods in the parent class. Each of these methods may define an independent functionality. The Template Method pattern provides an orchestrated approach to this.

It is based on a method in the parent abstract class. This method sequentially calls several individual abstract methods within the parent class. The subclasses just need to provide an implementation to these abstract methods. The template method definition in the base class takes care of appropriately invoking these individual methods.

The Template Method Design Pattern has only two participants

  • The Abstract Template Class: This contains the templateMethod(). This method is defined as final - so that it cannot be overridden. All operations used by this template method are made abstract, so their implementation is deferred to subclasses.
  • Concrete Class: This implements all the operations required by the templateMethod that were defined as abstract in the parent class. There can be many different Concrete Classes

Visitor Pattern


The behavior of any real world application is dynamic. It changes based on various factors around it. The Visitor pattern helps an object accept the behavior of a visiting class. This makes it easy to plug and play the visitor with the element.

  • Client: The Client class is a consumer of the classes of the visitor design pattern. It has access to the data structure objects and can instruct them to accept a Visitor to perform the appropriate processing.
  • Visitor: This is an interface or an abstract class used to declare the visit operations for all the types of visitable classes.
  • ConcreteVisitor: For each type of visitor all the visit methods, declared in abstract visitor, must be implemented. Each Visitor will be responsible for different operations.
  • Visitable: This is an interface which declares the accept operation. This is the entry point which enables an object to be “visited” by the visitor object.
  • ConcreteVisitable: These classes implement the Visitable interface or class and defines the accept operation. The visitor object is passed to this object using the accept operation.