Common Concepts in Design Pattern
Delegation & Composition
Abstraction, New Interface
- Chain of Responsibility
Limit Object Creation, Save Resource
Input at Runtime
- Chain of Responsibility
- Chain of Responsibility
Step of Process
- Template Method
Creational Design Pattern
- Sometimes creational patterns are competitors: there are cases when either Prototype or Abstract Factory could be used.
- At other times they are complementary: Abstract Factory might store a set of Prototypes from which to clone and return product objects. Abstract Factory, Builder, and Prototype can use Singleton in their implementation.
- Abstract Factory can be used as an alternative to Facade to hide platform-specific classes.
- Builder focuses on constructing objects step by step. Abstract Factory focuses in creating families of related objects.
- Builder lets you customize construction steps of objects. Abstract Factory returns the objects immediately.
- You can use Builder to create Composite by recursive construction steps.
- You can combine Builder with Bridge: the director class of Bridge act as abstraction, while Builder can act as implementation.
- Prototype can help when you need to save copies of Commands into history.
- Prototype can be used as simpler form of Memento, in case that state you want to store in the history, is fairly straightforward.
- Applying the Prototype lets you clone complex structures like Composite.
Structural Design Pattern
- Adapter provides new interface with same functionality. Proxy provides the same interface with new functionality. Decorator provides an enhanced interface with new functionality.
- Decorator supports recursive composition, which isn’t possible with Adapters.
- Bridge separate the abstraction and the implementation. Adapter make unrelated classes work together.
- Composite and Decorator have similar structure since both rely on recursive composition to organize an open-ended number of objects.
- Decorator adds additional functionality to the wrapped object, while Composite just sums up its component’s results.
- Decorator and Proxy have similar structures, but very different intents — Proxy usually manages the life cycle of its service object on its own, whereas the composition of Decorators is always controlled by the client.
- Decorator can be add recursively, Proxy can’t
- Facade is similar to Proxy in that both abstract a complex object from client. Unlike Facade which defines a new interface, Proxy has the same interface as its object, which makes them interchangeable.
- Facade and Mediator have similar jobs — they try to organize collaboration between lots of subsystems.
- Facade defines a simplified interface to subsystems but it doesn’t introduce any new functionality. The subsystems are unaware of the Facade — subsystems can communicate to each other directly.
- Mediator centralizes communication between subsystems. Each subsystem is only know about the Mediator — subsystems cannot communicate to each other directly.
- You can implement shared components of the Composite as Flyweight to save some RAM.
- Flyweight would resemble Singleton as resource management.
- But there are two fundamental differences between these patterns — Singleton should be only one instance, whereas a Flyweight class can have multiple instances with different intrinsic states. The Singleton object can be mutable. Flyweight objects are immutable.
Behavioral Design Pattern
- Chain of Responsibility, Command, Mediator, and Observer, address how you can decouple senders and receivers, but with different trade-offs.
- Chain of Responsibility passes a sender request along a chain of potential receivers.
- Command specifies a unidirectional connection of sender-receiver.
- Mediator eliminates direct connections between senders and receivers, forcing them to communicate indirectly via Mediator.
- Observer lets multiple receivers dynamically subscribe and unsubscribe to sender at run-time.
Chain of Responsibility
- Chain of Responsibility and Decorator both rely on recursive composition to pass the execution.
- However, there are differences in detail of how to execute — The Chain of Responsibility handlers can execute arbitrary operations independently of each other. They can also stop passing the request further at any point.
- On the other hand, Decorator can extend the object’s behavior while keeping it consistent with the base interface. In addition, Decorator aren’t allowed to break or stop the flow of the request.
- Handlers in Chain of Responsibility can be implemented as Command. In this case, you can execute a lot of different operations over the same context object, represented by a request.
- There’s another approach, where the request itself is a Command. In this case, you can execute the same operation in a series of different contexts linked into a chain.
- Command and Memento act as tokens to be passed around and invoked at a later time. In Command, the token represents a request. With Memento, it represents the internal state of an object at a particular time.
- You can use Command and Memento together when implementing undo or queue.
- Command and Strategy may look similar because you can use both to parameterize an object to take action.
- However, they have very different intents — Command lets you defer execution of the operation by queuing or storing the history of commands, then execute commands to specific object from outside.
- On the other hand, Strategy usually describes different ways of doing things and let you swap these algorithms inside object and execute on its own.
- The abstract syntax tree of Interpreter is usually a Composite (therefore Iterator and Visitor are also applicable)
- Terminal symbols within Interpreter’s abstract syntax tree can be shared with Flyweight.
- Template Method is based on inheritance — it lets you alter parts of an algorithm by extending those parts in subclasses.
- Strategy is based on composition — Strategy uses delegation to vary the entire algorithm. you can alter parts of the object’s behavior by supplying it with different strategies that correspond to that behavior.
- Template Method works at the class level, so it’s static. Strategy works on the object level, letting you switch behaviors at runtime.
- You can treat Visitor as a powerful version of the Command. Its objects can execute operations over various objects of different classes.