Level 2 · 25 min
Behavioral Patterns II
Advanced behavioral patterns handle complex communication scenarios: chains of handlers, centralized communication hubs, double-dispatch visitors, and state restoration for undo.
Chain of Responsibility
Chain of Responsibility passes a request along a chain of potential handlers. Each handler decides whether to handle it or pass it to the next. Used in: middleware pipelines (Express.js, Servlet filters), exception handling, authorization chains. The sender doesn't know which handler will process the request. Order matters — security before business logic.
Mediator
Visitor adds new operations to element classes without changing them — double dispatch: the visitor's visit() method is selected based on both the visitor type and the element type. Used for: AST traversal, report generation, serialization. Memento captures and externalizes an object's state without violating encapsulation — enables undo/redo (editor history, game saves). GoF states Visitor's intent as: "Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates." (Gamma et al., Design Patterns, p.331). The GoF motivation comes from compilers: an abstract syntax tree (AST) needs type-checking, code optimization, and code generation — three different operations on the same stable hierarchy. Each becomes a Visitor: TypeCheckingVisitor, CodeGenVisitor, OptimizingVisitor. Java's own compiler (javac) and bytecode manipulation libraries like ASM and ByteBuddy use Visitor extensively for AST and bytecode traversal. Memento's real-world use is equally concrete: GoF notes that editors, database transaction logs, and undo stacks all require it — the key constraint is that only the originator (the object whose state is saved) creates and reads mementos, preserving encapsulation.
Visitor and Memento
Visitor adds new operations to element classes without changing them — double dispatch: the visitor's visit() method is selected based on both the visitor type and the element type. Used for: AST traversal, report generation, serialization. Memento captures and externalizes an object's state without violating encapsulation — enables undo/redo (editor history, game saves).
Code example
// Chain of Responsibility: request validation pipeline
interface ValidationHandler {
void setNext(ValidationHandler next);
void validate(OrderRequest req);
}
abstract class BaseValidator implements ValidationHandler {
private ValidationHandler next;
public void setNext(ValidationHandler next) { this.next = next; }
protected void passToNext(OrderRequest req) {
if (next != null) next.validate(req);
}
}
class AuthValidator extends BaseValidator {
public void validate(OrderRequest req) {
if (!req.hasValidToken()) throw new UnauthorizedException();
passToNext(req);
}
}
class StockValidator extends BaseValidator {
public void validate(OrderRequest req) {
if (!inventory.hasStock(req.items())) throw new OutOfStockException();
passToNext(req);
}
}