What if your code could pass requests like a relay race, smoothly and without confusion?
Why Chain of Responsibility pattern in LLD? - Purpose & Use Cases
Start learning this pattern below
Jump into concepts and practice - no test required
Imagine you have a customer support system where every request must be checked by multiple teams one after another. You manually write code that checks each team in order, and if one team can't handle it, you pass it to the next. This quickly becomes messy and hard to manage as teams or rules change.
Manually coding each step means lots of repeated if-else checks. It's slow to update because you must change many places. It's easy to make mistakes, like skipping a team or handling requests twice. The code becomes tangled and hard to read, making bugs common and fixing them painful.
The Chain of Responsibility pattern lets you link handlers in a chain. Each handler decides if it can process the request or passes it along. This keeps code clean, flexible, and easy to extend. You can add or remove handlers without changing others, making the system scalable and maintainable.
if (teamA.canHandle(request)) { teamA.handle(request); } else if (teamB.canHandle(request)) { teamB.handle(request); } else { teamC.handle(request); }
handlerA.setNext(handlerB).setNext(handlerC); handlerA.handle(request);
This pattern enables building flexible, easy-to-change systems where requests flow smoothly through a chain of handlers without tight coupling.
In a tech support center, a customer's issue is passed from a basic help desk to specialized teams automatically until someone can solve it, without the customer repeating their problem.
Manual checks cause tangled, hard-to-maintain code.
Chain of Responsibility creates a flexible chain of handlers.
It makes adding or changing handlers simple and safe.
Practice
Chain of Responsibility pattern in system design?Solution
Step 1: Understand the pattern's behavior
The Chain of Responsibility pattern allows a request to be passed along a chain of objects until one can handle it.Step 2: Compare options with the pattern's purpose
The options describing singleton (one instance), prototype (object copies), and strategy (interchangeable algorithms) refer to other design patterns, not Chain of Responsibility.Final Answer:
To pass a request along a chain of handlers until one handles it -> Option AQuick Check:
Chain of Responsibility = pass request along chain [OK]
- Confusing with Singleton or Strategy patterns
- Thinking it creates object copies
- Assuming it handles all requests at once
Solution
Step 1: Recall how handlers are connected
In Chain of Responsibility, each handler has a reference to the next handler to pass the request along.Step 2: Evaluate other options
Global static lists, shared databases, and independent handlers describe unrelated or incorrect linking methods that contradict the chain concept.Final Answer:
Each handler holds a reference to the next handler in the chain -> Option DQuick Check:
Handler links = next handler reference [OK]
- Using global lists instead of direct references
- Assuming handlers are independent
- Confusing with event broadcasting
class Handler:
def __init__(self, successor=None):
self.successor = successor
def handle(self, request):
if self.can_handle(request):
return f"Handled {request}"
elif self.successor:
return self.successor.handle(request)
else:
return "Not handled"
def can_handle(self, request):
return False
class ConcreteHandlerA(Handler):
def can_handle(self, request):
return request == 'A'
class ConcreteHandlerB(Handler):
def can_handle(self, request):
return request == 'B'
chain = ConcreteHandlerA(ConcreteHandlerB())
print(chain.handle('B'))What is the output of this code?
Solution
Step 1: Trace the request through the chain
The request 'B' is first checked by ConcreteHandlerA, which returns False for can_handle('B'). It passes the request to ConcreteHandlerB.Step 2: ConcreteHandlerB handles the request
ConcreteHandlerB's can_handle('B') returns True, so it returns "Handled B".Final Answer:
Handled B -> Option AQuick Check:
Request 'B' handled by second handler [OK]
- Assuming first handler handles all requests
- Confusing return values
- Missing the chain passing logic
class Handler:
def __init__(self, successor=None):
self.successor = successor
def handle(self, request):
if self.can_handle(request):
return f"Handled {request}"
else:
return "Not handled"
def can_handle(self, request):
return False
class ConcreteHandler(Handler):
def can_handle(self, request):
return request == 'X'
chain = ConcreteHandler()
print(chain.handle('Y'))What is the main issue here?
Solution
Step 1: Analyze the handle method logic
The handle method checks can_handle; if False, it returns "Not handled" immediately without passing to successor.Step 2: Identify missing chain passing
It should call self.successor.handle(request) if successor exists, but this is missing.Final Answer:
The handler does not pass the request to the successor -> Option CQuick Check:
Missing successor call breaks chain [OK]
- Forgetting to call successor.handle()
- Assuming can_handle always returns True
- Ignoring successor initialization
Solution
Step 1: Understand the logging severity flow
Logs should be handled at their level, and higher severity logs should continue down the chain for further handling.Step 2: Evaluate options for correct chain behavior
Each handler processes logs at its level and passes only higher severity logs to the next handler matches this: handlers process their level and pass higher severity logs onward. Each handler processes only its level and passes all logs to the next handler passes all logs regardless, which is inefficient. Each handler processes all logs regardless of severity and stops the chain stops chain prematurely. Each handler processes logs randomly without order is random and incorrect.Final Answer:
Each handler processes logs at its level and passes only higher severity logs to the next handler -> Option BQuick Check:
Process level, pass higher severity [OK]
- Passing all logs without filtering
- Stopping chain too early
- Ignoring severity order
