The before code has client logic deciding which handler to call, causing tight coupling and duplication. The after code creates a chain where each handler tries to process the request and passes it on if it cannot. This decouples client from handler logic and allows easy extension.
### Before: tightly coupled handlers
class HandlerA:
def handle(self, request):
if request == 'A':
return 'Handled by A'
else:
return None
class HandlerB:
def handle(self, request):
if request == 'B':
return 'Handled by B'
else:
return None
# Client code
request = 'B'
handler_a = HandlerA()
handler_b = HandlerB()
result = handler_a.handle(request)
if result is None:
result = handler_b.handle(request)
print(result)
### After: Chain of Responsibility pattern
class Handler:
def __init__(self, successor=None):
self.successor = successor
def handle(self, request):
handled = self.process_request(request)
if handled is None and self.successor:
return self.successor.handle(request)
return handled
def process_request(self, request):
raise NotImplementedError('Must override')
class HandlerA(Handler):
def process_request(self, request):
if request == 'A':
return 'Handled by A'
return None
class HandlerB(Handler):
def process_request(self, request):
if request == 'B':
return 'Handled by B'
return None
# Client code
handler_chain = HandlerA(HandlerB())
result = handler_chain.handle('B')
print(result)