Chain of Responsibility
Passes a request along a chain of handlers until one processes it.
Context
An HTTP request must pass through: authentication → rate-limiting → validation → logging → handler. Each step can either proceed or terminate.
Problem
If the steps are tightly coupled, you cannot reorder or reuse them.
Solution
Each handler only knows the next one; it decides whether to process, delegate, or both.
#Example in C#
public abstract class Middleware
{
private Middleware? _next;
public Middleware LinkWith(Middleware next) { _next = next; return next; }
public virtual bool Handle(Request r) => _next?.Handle(r) ?? true;
}
public class AuthMiddleware : Middleware
{
public override bool Handle(Request r)
{
if (r.User is null) { r.Response = "401"; return false; }
return base.Handle(r);
}
}
public class RateLimitMiddleware : Middleware
{
public override bool Handle(Request r) =>
r.Hits < 100 ? base.Handle(r) : (r.Response = "429") is not null && false;
}When NOT to use it
When the chain always has the same steps in the same order: a sequential method is simpler.
Tradeoffs
| Pro | Con |
|---|---|
| Reorder and reuse steps | Difficult to know who processed the request |
| Fits well with pipelines (HTTP, MediatR) | Risk of loops or unprocessed requests |
#behavioral #gof #chain