Behavioral Design Patterns
Behavioral design patterns are a category within software design patterns that focus on communication between
objects, how they interact and fulfill duties. Unlike structural and creational patterns, which are
concerned with object composition and object creation respectively, behavioral patterns are all about
efficient communication and the delegation of responsibilities among objects. They help in defining not
just how objects are composed, but also how they communicate within the application's architecture.
Behavioral patterns need to facilitate interaction between classes and objects, while in the same time, it ensures
those classes/objects are loosely coupled.
There are 10 behavioral patterns(originally 9 in the GoF book, but we added Null Object which is a specialized strategy, as a separate pattern):
- Chain of Responsibility: Delegates commands to a chain of processing objects.
- Command(also known as Action or Transaction): Encapsulates a request as an object, thereby allowing for parameterization of clients with queues, requests, and operations.
- Interpreter: Implements a specialized language's grammar for interpreting sentences in the language.
- Iterator: Provides a way to access the elements of an aggregate object sequentially without exposing its underlying representation.
- Mediator: Defines an object that encapsulates how a set of objects interact, promoting loose coupling by keeping objects from referring to each other explicitly.
- Memento: Provides the ability to restore an object to its previous state (undo via rollback).
- Observer: Defines a dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.
- State: Allows an object to alter its behavior when its internal state changes.
- Strategy: Enables selecting an algorithm's behavior at runtime.
- Template Method: Defines the skeleton of an algorithm in the superclass but lets subclasses override specific steps of the algorithm without changing its structure.
- Visitor: Lets you define a new operation without changing the classes of the elements on which it operates.
- Null Object: provides intelligent do nothing behavior, hiding the details from its collaborators.
Functional Classification of Behavioral Patterns
Behavioral patterns can be classified in several categories, based on their purpose.
Task Delegation
These taks and command delegation behavioral patterns focus on delegating tasks or commands down a chain, encapsulating
requests as objects, or interpreting language constructs, respectively. They emphasize the delegation of responsibility
to other objects or components to achieve a task.
Algorithmic Delegation
We grouped in Algorithmic Delegation category the patterns that delegate the specifics of algorithmic execution either
through composition (Strategy) or inheritance (Template Method). It highlights the flexibility in how
algorithms or behaviors can be specified and modified, showcasing two fundamental object-oriented principles.
- Strategy - uses composition to enable the dynamic swapping of algorithms at runtime, allowing objects to change their behavior by incorporating different strategy objects.
- Template Method - relies on inheritance to allow subclasses to override certain steps of an algorithm without altering its structure, providing a fixed template for executing tasks.
- Null Object: a particular case of strategy pattern, provides do nothing behavior, hiding the details from its collaborators.
State Management
Focusing on managing and preserving the internal states of objects, this category deals with how objects can change their
behavior based on their state and how they can revert to previous states without violating encapsulation.
- State: Allows an object to alter its behavior when its internal state changes.
- Memento: Provides the ability to restore an object to its previous state (undo via rollback).
Communication Management
This category of behavioral patterns are concerned with managing how objects communicate and interact, either by centralizing communication through
a mediator object or by defining a subscription mechanism where objects can observe and react to state changes in other objects.
- Mediator: centralizes complex communications and control logic between objects in the system.
- Observer: establishes a subscription mechanism to allow objects to watch and be notified of state changes in other objects.
Traversing Patterns
Dedicated to working with collections and elements within those collections, these patterns address how to traverse or operate on
elements without exposing the underlying data structures (Iterator) or adding new operations without changing the structures of the
elements (Visitor).
- Iterator: Provides a way to access the elements of an aggregate object sequentially without exposing its underlying representation.
- Visitor: Lets you define a new operation without changing the classes of the elements on which it operates.
Inheritance vs Composition-Based Patterns
We can categorize the design patterns based on the implementation paradigm they are based on: inheritance or compostion.
Inheritance-Based Patterns
Composition-Based Patterns
Most of the behavioral design patterns use composition to achieve dynamic behavior modification.
Patterns That Can Utilize Both
Some patterns can be implemented using both inheritance and composition, depending on the specific use case or preference.