Chain of Responsibility: Structure and Participants
Core Structure
The Chain of Responsibility pattern consists of three primary participants that work together to create a flexible request processing pipeline.
+ handle(request: Request): void
- canHandle(request: Request): bool
- canHandle(request: Request): bool
+ sendRequest(req: Request): void
Participant Roles
Handler Interface: Defines the contract for all handlers in the chain. It declares the handle() method for processing requests and the setNext() method for linking handlers together. The interface ensures that all concrete handlers follow the same protocol, making them interchangeable.
Concrete Handlers: Implement the Handler interface and contain the actual processing logic. Each concrete handler maintains a reference to the next handler in the chain. When a request arrives, the handler first checks if it can process the request using its canHandle() logic. If yes, it processes the request and optionally stops propagation. If no, it forwards the request to the next handler using nextHandler.handle(request). If no next handler exists, the request remains unhandled.
Client: Builds the chain by creating handler instances and linking them using setNext(). The client then initiates request processing by calling handle() on the first handler. The client does not need to know which handler will ultimately process the request, only that the chain will handle it appropriately.
Request Flow Pattern
Client → HandlerA.handle()
→ if canHandle: process and optionally stop
→ else: HandlerB.handle()
→ if canHandle: process and optionally stop
→ else: HandlerC.handle()
→ until handled or chain endssetNext() typically returns Handler to enable fluent chain building: handlerA.setNext(handlerB).setNext(handlerC).Two Processing Variants
Single Handler Processing: Once a handler processes the request, propagation stops. This is common in authentication or validation chains where only one handler should take action.
Multiple Handler Processing: All applicable handlers process the request sequentially. This is common in logging or middleware pipelines where each handler performs a specific action and then passes the request forward. In this variant, handlers call nextHandler.handle() after their own processing, not instead of it.