Chain of Responsibility
- lets you pass requests along a chain of handlers, upon receiving a request, each handler decides either to process the request or to pass it to the next handler in the chain
- transforming particular behaviors into stand-alone objects called handlers
usage
- when your program is expected to process different kinds of requests in various ways, but the exact types of requests and their sequences are unknown beforehand
- when it’s essential to execute several handlers in a particular order
- when the set of handlers and their order are supposed to change at runtime
- if you provide setters for a reference field inside the handler classes, you’ll be able to insert, remove or reorder handlers dynamically
pros
- can control the order of request handling
- Single Responsibility Principle (SRP)
- can decouple classes that invoke operations from classes that perform operations
- Open/Closed Principle
- can introduce new handlers into the app without breaking the existing client code
cons
- some requests may end up unhandled
relations
- Chain of Responsibility - Command - Mediator - Observer
- address various ways of connecting senders and receivers of requests
- Chain of Responsibility passes a request sequentially along a dynamic chain of potential receivers until one of them handles it
- Command establishes unidirectional connections between senders and receivers
- Mediator eliminates direct connections between senders and receivers, forcing them to communicate indirectly via a mediator object
- Observer lets receivers dynamically subscribe to and unsubscribe from receiving requests
- Chain of Responsibility - Composite
- when a leaf component gets a request, it may pass it through the chain of all of the parent components down to the root of the object tree
- Chain of Responsibility - Decorator
- very similar class structures
- both patterns rely on recursive composition to pass the execution through a series of objects
- there are several crucial differences:
- Chain of Responsibility handlers can execute arbitrary operations independently of each other, they can also stop passing the request further at any point
- Decorators can extend the object’s behavior while keeping it consistent with the base interface and aren’t allowed to break the flow of the request
Command
- turns a request into a stand-alone object that contains all information about the request