Chain of Responsibility: Definition and Purpose
What Problem Does It Solve?
The Chain of Responsibility pattern decouples the sender of a request from its receiver by giving multiple objects a chance to handle the request. This solves several key problems:
First, it eliminates tight coupling between request senders and specific handlers. Without this pattern, the sender must know exactly which handler to call and in what order, creating rigid dependencies.
Second, it allows dynamic runtime configuration of the processing chain. You can add, remove, or reorder handlers without modifying the sender or other handlers.
Third, it promotes the Single Responsibility Principle (SRP) by allowing each handler to focus on one specific processing concern, such as authentication, validation, or logging.
Real-World Analogy
Consider a customer support system. When you call support, your request might go through: First, an automated system checks if it is a common question. Second, a junior support agent tries to resolve it. Third, if unresolved, it escalates to a senior agent. Finally, if still unresolved, it reaches a specialist. Each level either handles the request or passes it along, without the customer knowing the internal routing logic.
Key Characteristics
Decoupled Handlers: Each handler is independent and only maintains a reference to the next handler, if any exists.
Request Propagation: A request travels through the chain until a handler processes it completely or the chain ends. Some implementations allow multiple handlers to process the same request.
Dynamic Chain Configuration: The chain can be built or modified at runtime, allowing flexible processing pipelines without code changes.