Behavioral Design Patterns

Learn via video courses

Introduction

Behavioral design patterns deal with the interaction of objects in an object-oriented software application. This article discusses various behavioral design patterns that help objects cooperate and interact with each other. Behavioral Design Patterns provides a set of guidelines formulated by software pioneers that identify common communication patterns among objects and provide a way to solve commonly occurring object-interaction-related problems in software design.

What is a behavioral design pattern?

Behaviour is how someone acts i.e., it consists of the tasks that one executes to interact in an environment. In object-oriented software development, the behaviour of different objects determines the relationship between them and also determines their ability to perform a certain task.

The ability of an object-oriented software application to accomplish a task depends upon the interaction of various objects and classes. To build efficient object-oriented software, we should follow some guidelines that describes how different objects and classes send messages to each other to make things happen. This is where Behavioral Design Patterns come into the picture. It is a collection of templates that revolve around designing the interaction between objects and classes.

Behavioral patterns follow the principle that the objects in an object-oriented application should be interconnected in such a way that hard coding can be avoided and the user input can be well handled. For this principle, the behavioral design patterns make use of loose coupling techniques to ensure a flexible and effective flow of information.

Loosely coupled object-oriented software systems are those in which the components (classes and objects) are weakly associated with each other. Due to this weak association between the components, the object interactions in loosely coupled systems are not as effective as that in tightly coupled systems. But, objects in a loosely coupled system are more independent and reusable as any changes made in one component have minimal effect on the existence or the performance of another component.

object-interactions

Hence, to take benefit from this extensibility of a loosely-coupled system, behavioral design patterns are used which can help objects cooperate and communicate with each other while they are loosely coupled. This effect can be noticed in the above figure where the two objects O1 and O2 are able to interact with each other (O1 and O2 sends messages msg and MSG to each other respectively), even in a loosely coupled configuration using Behavioral Design Patterns. This provides the flexibility and independence of objects in an application and also maintains the interactions between them. Making use of behavioral patterns can reduce complicated software design structures into a simpler cluster of interconnections between several objects.

Types of Behavioral Design Patterns

There are 12 different types of behavioral patterns as described in the Design Patterns: Elements of Reusable Object-Oriented Software book (also called the Gang of Four). Behavioral design patterns include:

Chain of Responsibility Pattern

It is a behavioral design pattern that allows us to pass a request between a chain of objects. Each object in the chain contains its processing logic that performs some action and decides the next object from the chain to delegate the work. It is used in decoupling the sender from the receiver.

When to use Chain of Responsibility Pattern

  • When we wish to decouple the request's sender from its receiver.
  • When the request provided to the application can be handled by passing it to a series of objects.
  • When we need to enhance the flexibility of the duties assigned to objects.

Command Pattern

It is a data-driven behavioral pattern that turns a request into a stand-alone object known as a command. It encapsulates all the information that is required to act i.e., it wraps the action and its required parameters together in an object. It is used to separate the object that invokes the operation from the object that operates.

When to use Command Pattern

  • When we need to attach operations with objects using which we can queue operations, schedule their execution, or execute them remotely.
  • When we wish to implement reversible operations like undo and redo operations. Since the command pattern allows us to create objects that represent the actions that are to be performed in the application, we can create a list of tasks performed (list of command objects) and can undo or redo the task just by searching and executing the undo method of the last command object from the task list.

Interpreter Pattern

It is a behavioral pattern that is used to incorporate specialized computer language elements in programs to solve a specific set of problems. It is used to write simple programs that understand human-like syntax.

When to use Interpreter Pattern

  • When we wish to provide human-like syntax to the clients and hide the application's structure complexity from the clients.
  • When we wish to define a grammatical representation for a domain-specific language and provide an interpreter to deal with this grammar.

Iterator Pattern

An iterator pattern is a type of behavioral pattern that is used to sequentially access the elements of a collection without exposing its underlying or internal representation.

When to use Iterator Pattern

  • When we wish to provide a way to access and traverse the elements of a collection without revealing the internal data structures to the clients.
  • When we want the application to traverse different data structures.

Mediator Pattern

The mediator pattern is used to simplify the communication between multiple objects or classes. It provides a mediator class that handles all the interactions going on between different objects or classes. This pattern also promotes loose coupling by keeping objects from referring to each other explicitly.

When to use Mediator Pattern

  • When the application consists of such a large number of objects that it becomes difficult to manage their references.
  • When it is difficult to change some classes because of the presence of tight coupling.

Memento Pattern

The memento pattern is used to implement the undo operation i.e., it allows us to save and restore an object to its previous state. It wraps the entire object state in a single object known as the Memento that allows the entire state to be saved and restored in a single action.

When to use Memento Pattern

  • When we wish to produce the snapshots of the object's state to get the ability to restore the previous states of an object. The snapshot of an object represents its state at a particular instance in time in an object-oriented application.

Observer Pattern

An observer pattern is a behavioral pattern that is used to monitor the state of multiple objects or classes. It acts as a notifier of change to multiple classes. Using the observer pattern, the change in the state of an object is reflected among other objects in the application.

When to use Observer Pattern

  • When modifications in the state of one object require a change in other objects.
  • When some objects must observe other objects only for a limited time or in specific cases.

State Pattern

A state pattern is a behavioral design pattern that is used when a specific object needs to change its behaviour based on its internal state. It provides a way for an object to partially change its type at runtime. It appears as if the object changed its class at runtime.

When to use State Pattern

  • When we have an object that behaves differently depending on its current state.
  • When we wish to implement different class behaviours according to the current values of the class’s fields.

Strategy Pattern

A strategy pattern or Policy pattern is a behavioral design pattern that helps us to write a generic code that gives us specific behaviour needed for given use cases. It allows us to select both the behaviour and the algorithm at runtime, based on the input of the client.

When to use Strategy Pattern

  • When we have a use case of deciding how the objects will behave dynamically.
  • When we want to use different variants of an algorithm within an object and be able to switch from one algorithm to another during runtime.

Template Pattern

A template pattern is used to define the framework of an algorithm in the superclass and lets the subclasses redefine certain steps of an algorithm without changing the overall algorithm's structure.

When to use Template Pattern

  • When several classes contain almost identical algorithms and we need to modify all the classes when there is a change in the algorithm.
  • When we want to allow the clients to extend only particular steps of an algorithm, but not the whole algorithm or its structure.

Visitor Pattern

The visitor design pattern is used to separate an algorithm from the object structure on which it operates. It allows us to define and add new operations to the existing classes without affecting the existing structure.

When to use Visitor Pattern

  • When we wish to perform an operation on all the elements of a complex object structure.
  • When we wish to extend the interface of the primary type by creating a separate class hierarchy.

Null Object Pattern

A null object pattern is used to design a null object that conveys the absence of an object or acts as the default value of an object. It is used to minimize the null-checks in an application.

When to use Null Object Pattern

  • When we want to minimize the null-checks in an application.
  • When we want to perform a null-check to skip the execution or perform a default action.

What are the Problems Solved by Behavioral Design Patterns?

  • It reduces the complexity of communication between the objects.
  • It provides the best object interaction principles of software development.
  • It reduces the coupling between the senders and the receivers and enables better communication flexibility in the application.
  • It is used to save the number of resources being used by an application as better object interaction leads to better task execution.

Conclusion

In this article we learned:

  • What is a behavioral design pattern?
  • How each behavioral design pattern differs from one another and the specific use case in which a pattern is applied.
  • Finally, we have discussed the problems that are solved by behavioral design patterns and why it is efficient in building an object-oriented application.