-
Notifications
You must be signed in to change notification settings - Fork 2
3. Behavioral Patterns
Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.
The Chain of Responsibility pattern works with a list of Handler objects that have limitations on the nature of the requests they can deal with. If an object cannot handle a request, it passes it on to the next object in the chain. At the end of the chain, there can be either default or exceptional behavior.
Use the Chain of Responsibility pattern when… You have:
- More than one handler for a request
- Reasons why a handler should pass a request on to another one in the chain
- A set of handlers that varies dynamically You want to:
- Retain flexibility in assigning requests to handlers
Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.
Use the Command pattern when… You have:
- Commands that different receivers can handle in different ways
- A high-level set of commands that are implemented by primitive operations You want to:
- Specify, queue, and execute commands at different times
- Support an Undo function for commands
- Support auditing and logging of all changes via commands
Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language.
Use the Interpreter pattern when… You have a grammar to be interpreted and:
- The grammar is not too large.
- Efficiency is not critical.
- Parsing tools are available.
- XML is an option for the specification.
Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.
Use the Iterator pattern when… You are iterating over a collection and one of these conditions holds:
- There are various ways of traversing it (several enumerators).
- There are different collections for the same kind of traversing.
- Different filters and orderings might apply.
Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently.
Use the Mediator pattern when…
- Objects communicate in well-structured but potentially complex ways.
- The objects’ identities should be protected even though they communicate.
- Some object behaviors can be grouped and customized.
Without violating encapsulation, capture and externalize an object's internal state so that the object can be restored to this state later.
Use the Memento pattern when…
- An object’s state must be saved to be restored later,and
- It is undesirable to expose the state directly.
Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.
Use the Observer pattern when…
- There are aspects to an abstraction that can vary independently.
- Changes in one object need to be propagated to a selection of other objects, not all of them.
- The object sending the changes does not need to know about the receivers.
Allow an object to alter its behavior when its internal state changes. The object will appear to change its class.
Use the State pattern when… You have objects that:
- Will change their behavior at runtime, based on some context
- Are becoming complex, with many conditional branches You want to:
- Vary the set of handlers for an object request dynamically
- Retain flexibility in assigning requests to handlers
Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.
Use the Strategy pattern when…
- Many related classes differ only in their behavior.
- There are different algorithms for a given purpose, and the selection criteria can be codified.
- The algorithm uses data to which the client should not have access.
Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure.
Use the Template Method pattern when…
- Common behavior can be factored out of an algorithm.
- The behavior varies according to the type of a subclass.
Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates.
Use the Visitor pattern when…
- You have a class hierarchy that is effectively sealed.
- There are many distinct operations to perform on it.
- The operations are orthogonal to the core purpose of the types in the hierarchy.
- You need the flexibility to define new operations over time.