Behavioral Design Patterns
Patterns for communication between objects: Observer, Strategy, Command, Iterator, State, Template Method, Visitor, Mediator, Chain of Responsibility, Interpreter.
Patterns for communication between objects: Observer, Strategy, Command, Iterator, State, Template Method, Visitor, Mediator, Chain of Responsibility, Interpreter.
Behavioral design patterns that assign responsibilities and manage communication: Observer, Strategy, Command, Iterator, State, Template Method, Visitor, Mediator, Chain of Responsibility and Interpreter, each with intent, structure, uses, pros, cons and related patterns.
| Name | Intent | Also known as | Structure brief | Use cases | Pros | Cons | Implementation notes | Related patterns | Also known as as |
|---|---|---|---|---|---|---|---|---|---|
| Observer | Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified automatically. | Publish-Subscribe, Event-Subscriber | Subject maintains list of Observer objects; notifies them on state change via update() method. |
| Loose coupling (subject doesn't know observer details), dynamic subscription/unsubscription, supports broadcast communication. | Memory leaks if observers not unregistered, unexpected updates can cause performance issues, hard to debug due to indirect flow. | Push vs pull models: push sends data with notification; pull observers query subject. Thread safety required in concurrent systems. Java's java.util.Observer deprecated in favor of PropertyChangeListener and modern event buses. |
| null |
| Strategy | Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it. | Policy Pattern | Context class delegates to a Strategy interface; concrete strategies implement different algorithms. |
| Eliminates conditional statements, algorithms are isolated (open/closed), easy to add new strategies, enables runtime strategy switching. | Client must know strategies to choose appropriately, increased number of objects, may be overkill for only 1-2 strategies. | Strategies often passed via constructor (dependency injection) or setter. Can be combined with Factory to auto-select strategy. Functional programming often replaces with first-class functions/lambdas. |
| null |
| Command | Encapsulate a request as an object, thereby allowing parameterization of clients with different requests, queuing of requests, and support for undoable operations. | null | Command interface declares execute(); ConcreteCommand binds Receiver and invokes its action; Invoker holds and calls command; Client creates concrete command. |
| Decouples sender and receiver, easy to add new commands, supports undo/redo via Memento, enables command queuing and logging. | Can lead to many small command classes, complexity increases with composite commands, may not be necessary for simple direct calls. | Command often includes undo() method. Macro commands combine multiple commands. Command pattern is foundation of CQRS (Command Query Responsibility Segregation). Used heavily in Android onClick listeners and iOS target-action. |
| Action, Transaction |
| Iterator | Provide a way to access elements of an aggregate object sequentially without exposing its underlying representation. | Cursor | Iterator interface defines next(), hasNext(); ConcreteIterator tracks position; Aggregate creates iterator; Collection implements iteration logic separately. |
| Single Responsibility (collection vs iteration), multiple simultaneous iterators, simplifies client code, supports different traversal strategies. | Increased complexity for simple collections, overhead for small data sets, mutable collections may require careful iterator invalidation. | Modern languages often have built-in iterators/generators (Python yield, JavaScript generator functions, C# IEnumerable). Fail-fast iterators throw ConcurrentModificationException if collection modified during iteration. External iterator (client controls iteration) vs internal iterator (collection controls). |
| null |
| State | Allow an object to alter its behavior when its internal state changes. The object will appear to change its class. | State Machine | Context delegates to State interface; ConcreteState implements behavior for that state; State transitions change Context's state object. |
| Eliminates large conditional statements on state, state-specific logic is localized, easier to add new states, adheres to Open/Closed Principle. | Can be over-engineered for simple state changes, many small state classes increase class count, state transition logic can be scattered. | State transitions may be triggered by context or by state objects. Can be implemented with polymorphism or with state pattern tables. Finite State Machine (FSM) libraries often implement this. States can be implemented as singletons if stateless. |
| null |
| Template Method | Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps without changing the algorithm's structure. | null | AbstractClass defines templateMethod() with invariant steps and abstract/primitives for variant steps; ConcreteClass implements variant steps. |
| Code reuse (common algorithm in base), inversion of control (Hollywood Principle: "Don't call us, we'll call you"), enforces algorithm structure. | Base class can become bloated, limited flexibility (subclasses can only override specific steps), may require many small subclasses. | Template method often final to prevent overriding of skeleton. Hook methods do nothing by default; override selectively. Should call parent implementation or completely replace. Used extensively in Java's AbstractList, AbstractMap. |
| Template Pattern |
| Visitor | Represent an operation to be performed on elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates. | Visitor interface declares visit methods per element type; ConcreteVisitor implements operations; Element interface declares accept(Visitor); ConcreteElement calls visitor.visit(this). |
| Adding new operations is easy (new visitor), related operations are grouped together, can accumulate state during traversal, Visitor can work across unrelated classes. | Breaks encapsulation (visitor accesses internals), fragile to element class changes (must update all visitors), element hierarchy must be stable, difficult to add new element types. | Visitor requires accept() method on all elements. Double dispatch: visitor's method chosen by both visitor type AND element type. Used in Java's FileVisitor (NIO.2) and Expression trees. Considered complex and often overused. |
| null | |
| Mediator | Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly and lets you vary their interaction independently. | Intermediary, Controller | Mediator interface defines communication methods; ConcreteMediator coordinates Colleagues; Colleagues communicate only through Mediator. |
| Centralizes complex communication, reduces coupling between colleagues, easier to understand interaction flow, each colleague only knows Mediator. | Mediator can become god object (too many responsibilities), introduces single point of failure, colleague changes may still require Mediator changes. | Mediator often implemented as event bus or message broker. In web dev, Redux/Vuex/Pinia act as state mediators. Colleagues register callbacks with Mediator. Can be combined with Observer pattern where Mediator observes Colleagues. |
| null |
| Chain of Responsibility | Avoid coupling sender of a request to receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass request along chain until handled. | null | Handler interface defines handle(request) and sets next handler; ConcreteHandler processes or forwards; Clients set up chain and send to first. |
| Decouples sender and receiver, flexibility in assigning responsibilities at runtime, can add/remove handlers dynamically, simplifies objects (each handles one concern). | Request may go unhandled, hard to debug flow (which handler?), order matters critically, may have performance overhead for long chains. | Chain built explicitly or via configuration. Can be static or dynamic. Each handler decides whether to handle and stop propagation, or pass to next. In web frameworks, middleware order is critical. Stop propagation via returning response or throwing exception. |
| Responsibility Chain |
| Interpreter | Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language. | AbstractExpression declares interpret() method; TerminalExpression implements leaf nodes; NonTerminalExpression combines sub-expressions; Context holds global state (optional). |
| Easy to extend grammar (new expressions), straightforward implementation for simple languages, changing/growing grammar is easy. | Complex grammars require many classes, inefficient for complex languages (better to use parser generators), maintains interpreter class per rule (maintenance). | Best for simple grammars; complex languages use parser generators (ANTLR, Yacc). Interpret() often recursive. Abstract Syntax Tree (AST) built first, then interpreted. Can add operations via Visitor without modifying expressions. Used in JavaScript's eval, Python's ast module. |
| null |
The shape of this dataset, read from the data itself: every column, its type and a real value. Agents can use this to plan a query without fetching the whole document.
| Section | Field | Type | Example |
|---|---|---|---|
| patterns | name | string | Observer |
| patterns | intent | string | Define a one-to-many dependency between objects… |
| patterns | also_known_as | string | Publish-Subscribe, Event-Subscriber |
| patterns | structure_brief | string | Subject maintains list of Observer objects; not… |
| patterns | use_cases | array | [5 items] |
| patterns | pros | string | Loose coupling (subject doesn't know observer d… |
| patterns | cons | string | Memory leaks if observers not unregistered, une… |
| patterns | implementation_notes | string | Push vs pull models: push sends data with notif… |
| patterns | related_patterns | array | [4 items] |
| patterns | also_known_as_as | string | Action, Transaction |
The static files contain the same reference rows as the API, with no API rate limit. Live metadata, such as view counts, may differ. Use the API for content negotiation; use the static files for a cacheable snapshot.
curl "https://yjtoon.yunusemrevurgun.com/api/dataset/behavioral-design-patterns?format=toon"
const res = await fetch( "https://yjtoon.yunusemrevurgun.com/static-data/dataset/behavioral-design-patterns.toon" ); const toon = await res.text();
Rate limit: 120 requests per minute per IP, no key and no signup. API reference →