Chain of Responsibility & Template Method
You'll learn to
- -Build a chain of handlers where each either processes a request or passes it along, as in a middleware/logging pipeline
- -Use Template Method to fix an algorithm's skeleton in a base class while letting subclasses override individual steps
These two patterns are grouped together because both are about structuring a multi-step process, but from opposite directions: Chain of Responsibility lets any number of independent handlers each decide whether to act, in sequence. Template Method fixes the overall sequence in one place and lets subclasses customize individual steps.
Chain of Responsibility: A Pipeline of Independent Handlers
Each handler in the chain gets a chance to process a request, and either handles it, passes it to the next handler, or does both. A logging framework is the canonical example: a log message passes through a chain of handlers (DebugHandler, InfoHandler, ErrorHandler), each checking whether it is responsible for this log level, with the sender never needing to know which handler ultimately processes the message.
class Handler(ABC):
def __init__(self):
self._next: Handler | None = None
def set_next(self, handler: "Handler") -> "Handler":
self._next = handler
return handler # allows chaining: h1.set_next(h2).set_next(h3)
def handle(self, request: str) -> None:
if self._next:
self._next.handle(request) # pass along if this handler doesn't fully handle it
class AuthenticationHandler(Handler):
def handle(self, request: str) -> None:
print("Checking authentication...")
if not request.startswith("Authorization: "):
print("Rejected: no credentials")
return # short-circuits - never calls super().handle()
super().handle(request) # only passes along once authenticated
class RateLimitHandler(Handler):
def handle(self, request: str) -> None:
print("Checking rate limit...")
super().handle(request)
class LoggingHandler(Handler):
def handle(self, request: str) -> None:
print(f"Logging request: {request}")
super().handle(request)
chain = AuthenticationHandler()
chain.set_next(RateLimitHandler()).set_next(LoggingHandler())
chain.handle("GET /orders") # rejected - never reaches RateLimitHandler or LoggingHandler
chain.handle("Authorization: Bearer xyz GET /orders") # passes auth, flows through all threeThis is the exact structural shape behind most web framework middleware pipelines: each middleware either short-circuits the request (AuthenticationHandler above rejects an unauthenticated call by simply returning instead of calling super().handle()) or passes it to the next one, and adding a new cross-cutting concern (rate limiting, logging, compression) means inserting one new handler into the chain, with zero changes to the others.
Template Method: One Fixed Skeleton, Customizable Steps
Template Method defines the skeleton of an algorithm in a base class method, deferring some steps to subclasses - the overall sequence never changes, but individual steps do. A data-processing pipeline that always reads, transforms, then writes data, but where "read" and "write" differ by source (CSV vs. JSON), is a natural fit.
class DataProcessor(ABC):
def process(self) -> None: # the template method - never overridden
data = self.read_data()
transformed = self.transform(data)
self.write_data(transformed)
@abstractmethod
def read_data(self) -> list: ...
def transform(self, data: list) -> list: # has a sensible default, can still be overridden
return data
@abstractmethod
def write_data(self, data: list) -> None: ...
class CSVProcessor(DataProcessor):
def read_data(self) -> list: return read_csv_file()
def write_data(self, data: list) -> None: write_csv_file(data)The interview-relevant distinction between the two: Chain of Responsibility is about which handler(s) run, decided dynamically at runtime by each handler. Template Method is about which steps run, fixed at compile time by the base class - only the content of each step varies.
Interview Signal is part of Pro
See a real weak answer next to a real strong one for this exact topic.
Quiz is part of Pro
Test what you just read with a short quiz, and bank the XP.