Intuition The one-sentence soul of
behavioral patterns
Creational patterns answer "how do I make objects?" , structural patterns answer "how do I compose objects?" , and behavioral patterns answer "how do objects talk to each other and divide responsibility?" — they are about the flow of communication and control at runtime.
Intuition The root problem
When two pieces of code know too much about how each other works, they become welded together. Change one, you must change the other. Behavioral patterns insert a thin, agreed-upon contract (an interface or a message) between collaborators so that who-does-what can vary independently of who-calls-whom .
The recurring trick in every pattern below is the same: replace a hard-coded if/switch or a direct method call with an object you can swap, store, queue, or notify.
Definition Quick contracts
Observer ::: one subject notifies many dependents automatically when its state changes (publish/subscribe).
Strategy ::: encapsulate interchangeable algorithms behind one interface; pick at runtime.
Command ::: turn a request into an object (so you can queue, log, undo it).
Iterator ::: traverse a collection without exposing its internal structure.
State ::: let an object change its behavior when its internal state changes (looks like it changed class).
Template Method ::: define the skeleton of an algorithm in a base method , defer steps to subclasses.
Chain of Responsibility ::: pass a request along a chain of handlers until one handles it.
Mediator ::: a central object coordinates communication between many colleagues (many-to-many → star).
Memento ::: capture and restore an object's internal state without breaking encapsulation (snapshots).
Visitor ::: add new operations to a class hierarchy without modifying the classes.
A spreadsheet cell, a chart, and a status bar all need to update when data changes. Hard-coding data.update(); chart.update(); bar.update() means the data layer must know about the UI. Bad. Instead the data broadcasts "I changed" and anyone who cares listens.
Subject keeps a list of Observers . On state change it calls notify(), which loops calling observer.update(). Observers subscribe/unsubscribe at runtime . The subject knows observers only through an interface, not their concrete class.
Worked example Minimal Observer (Python) —
Why each step?
class Subject :
def __init__ (self):
self ._observers = [] # Why: subject owns the list, not the observers
def subscribe (self, o): self ._observers.append(o)
def unsubscribe (self, o): self ._observers.remove(o)
def notify (self, data):
for o in self ._observers: # Why: loop = decoupled fan-out
o.update(data) # Why: calls interface method, not concrete code
class Logger :
def update (self, data): print ( "LOG:" , data)
s = Subject(); s.subscribe(Logger())
s.notify( "temp=42" ) # LOG: temp=42
Why no return value? Observer is push ; the subject does not wait for or care about answers.
Common mistake Steel-man: "Just call the UI directly from the model, it's simpler."
It feels simpler because for two objects it is fewer lines. The fix: it stops scaling — every new observer edits the model, and the model can't be unit-tested without the UI. Observer trades 5 lines of plumbing for O(1) cost to add new listeners.
You have one task (sort, compress, route) with many algorithms . A giant if mode == "quick": ... elif mode == "merge": ... is a maintenance bomb. Strategy makes each algorithm a swappable object.
A Context holds a reference to a Strategy interface and delegates to strategy.execute(). Concrete strategies implement it differently. The client chooses the strategy; the context never knows which one.
class Context :
def __init__ (self, strategy): self .strategy = strategy
def do (self, data): return self .strategy(data) # delegate, no if/else
Context( sorted ).do([ 3 , 1 , 2 ]) # ascending
Context( lambda d: sorted (d, reverse = True )).do([ 3 , 1 , 2 ]) # descending
Why pass a function? In Python a function is a strategy object — minimal Strategy needs no class.
Common mistake "State and Strategy look identical — same UML!"
True, the structure is twins. The fix is intent : Strategy's objects are independent, picked by the client and don't know about each other. State's objects know the next state and trigger transitions themselves.
A button's click handler shouldn't contain the logic of what it does — otherwise you can't undo it, queue it, schedule it, or log it. Wrap "the thing to do" in an object with execute() (and undo()).
A Command object stores the receiver , the method , and the arguments . An Invoker (button, queue) just calls command.execute(). This turns a verb into a noun , enabling undo/redo, macros, and job queues.
class AddText :
def __init__ (self, doc, text): self .doc, self .text = doc, text
def execute (self): self .doc.append( self .text)
def undo (self): self .doc.pop() # Why: store enough to reverse
history = []
def run (cmd): cmd.execute(); history.append(cmd)
def undo (): history.pop().undo()
Why keep a history list? Because commands are now first-class objects you can stack them — that's literally Ctrl-Z.
You want for x in collection to work the same whether it's a tree, a list, or a database cursor — without exposing whether it's an array or linked nodes.
An Iterator exposes next() / has_next() (in Python __next__ + StopIteration). The collection produces an iterator via __iter__. Traversal state lives in the iterator, not the collection , so multiple traversals run independently.
class Countdown :
def __init__ (self, n): self .n = n
def __iter__ (self): # Why: returns a fresh iterator
i = self .n
while i > 0 :
yield i # Why: generator = iterator for free
i -= 1
list (Countdown( 3 )) # [3, 2, 1]
A document is Draft → Moderation → Published. Coding this as if self.status == ... everywhere duplicates the transition rules. State puts each status's behavior in its own class.
The Context delegates behavior to a current State object. Each state decides the next state and tells the context to switch . Adding a status = adding a class, not editing every method.
class Draft :
def publish (self, ctx): ctx.state = Published()
class Published :
def publish (self, ctx): print ( "already live" )
class Doc :
def __init__ (self): self .state = Draft()
def publish (self): self .state.publish( self )
Why pass ctx? So the state can mutate the context's state field — that is the transition.
Two algorithms share 80% of their steps but differ in one. Don't copy-paste; freeze the skeleton in a base class and let subclasses fill the holes.
A base class defines a final method calling abstract hook steps in fixed order. Subclasses override the steps, never the order. (Inversion of control: "don't call us, we'll call you.")
class Report :
def generate (self): # the template — fixed skeleton
self .header(); self .body(); self .footer()
def header (self): print ( "=== Report ===" )
def body (self): raise NotImplementedError # hook
def footer (self): print ( "--- end ---" )
class Sales ( Report ):
def body (self): print ( "sales: 100" )
Strategy vs Template Method? Strategy varies an algorithm via composition (an object you pass in); Template Method via inheritance (override a method).
A support ticket might be handled by L1, escalated to L2, then a manager. The sender shouldn't know who finally handles it.
Each Handler has a next link. It either handles the request or ==passes it to next==. The chain stops at the first handler that succeeds (or runs off the end).
class Handler :
def __init__ (self, limit, nxt = None ): self .limit, self .nxt = limit, nxt
def handle (self, amount):
if amount <= self .limit: print ( f "approved by {self .limit } -handler" )
elif self .nxt: self .nxt.handle(amount) # Why: pass along
else : print ( "rejected" )
chain = Handler( 100 , Handler( 1000 ))
chain.handle( 500 ) # approved by 1000-handler
If 5 UI widgets all reference each other, that's potentially 5×4 = 20 connections — a tangled mesh. Route everything through one mediator and it becomes a clean star (5 connections).
Colleagues don't talk to each other directly; they send events to a Mediator , which decides who else to notify. Turns a many-to-many web into a hub-and-spoke. (Note: Observer is generic broadcast; Mediator encodes specific coordination logic.)
To support undo you need a snapshot of an object's private state — but exposing those privates breaks encapsulation. Memento stores the snapshot in an opaque box only the originator can read.
Originator creates a Memento holding its state; a Caretaker stores mementos (the undo stack) without ever inspecting them . Restore = originator.restore(memento).
class Editor :
def __init__ (self): self .text = ""
def save (self): return self .text # the memento (opaque to caretaker)
def restore (self, m): self .text = m
e = Editor(); e.text = "hi" ; snap = e.save()
e.text = "bye" ; e.restore(snap) # back to "hi"
Memento vs Command-undo? Command remembers how to reverse an action ; Memento remembers the whole state . Use Memento when reversing is hard but snapshotting is cheap.
You have a stable class hierarchy (Circle, Square, Triangle) and keep adding operations (area, draw, export). Adding each operation to every class is invasive. Visitor moves the operations out into visitor objects.
Each element implements accept(visitor) which calls visitor.visitX(self) — this double dispatch picks the right method by both the element type and the visitor type. ==Add a new operation = add a new Visitor class, touch zero element classes.==
class Circle :
def accept (self, v): return v.visit_circle( self ) # double dispatch
class AreaVisitor :
def visit_circle (self, c): return 3.14159 * c.r ** 2
The trade-off: Visitor makes adding operations easy but adding a new element type hard (every visitor must change). It's the mirror image of normal OOP.
Intuition If you forget everything else
Observer + Strategy + Command are ~80% of real-world usage. Master these three cold.
Every behavioral pattern = replace a hard-coded call/if with a swappable object .
Look-alikes by intent: Strategy vs State (client-picks vs self-transitions), Strategy vs Template Method (composition vs inheritance), Mediator vs Observer (specific coordination vs generic broadcast), Memento vs Command-undo (full snapshot vs reversible action).
"On Saturday, CICS, To Catch More Mistakes, Visit."
O bserver · S trategy · C ommand · I terator · C (State→"Change") · T emplate · C hain · M ediator · M emento · V isitor.
Recall Feynman: explain to a 12-year-old
Imagine a classroom.
Observer : the teacher rings a bell and everyone who chose to listen reacts. (broadcast)
Strategy : you can solve a maths problem by adding, or by counting on fingers — you pick the method and the problem doesn't care.
Command : you write a chore on a sticky note ("take out trash"). Now you can give it to someone later, or tear it up (undo).
Iterator : a remote with a "next channel" button — you don't need to know how the TV stores channels.
State : a traffic light behaves differently depending on its colour, and it decides when to switch itself.
Template Method : a recipe with fixed steps where you choose the filling.
Chain of Responsibility : you ask a question; if the first kid doesn't know, they pass it to the next, and so on.
Mediator : instead of all kids shouting at each other, they all talk through the teacher.
Memento : you take a photo of your Lego build so you can rebuild it exactly if it breaks.
Visitor : a guest comes and does one job (counts toys) to every toy, without changing the toys.
What single problem do ALL behavioral patterns address? How objects communicate and how responsibilities are divided at runtime (flow of control/messaging), via a thin contract that decouples collaborators.
Observer: who owns the subscriber list and what does notify() do? The subject owns the list; notify() loops over observers calling each observer's update() through an interface — a decoupled fan-out broadcast.
Strategy vs State — same UML, what's the difference? Intent. Strategy objects are independent and chosen by the client ; State objects know each other and self-trigger transitions on the context.
Strategy vs Template Method? Strategy varies an algorithm via composition (object passed in); Template Method via inheritance (override hook steps in a fixed skeleton).
Command pattern turns a ___ into a ___, enabling what 3 things? A request into an object; enabling undo/redo, queuing/scheduling, and logging.
What is the key benefit of Iterator? Traverse a collection without exposing its internal representation; traversal state lives in the iterator so multiple independent traversals are possible.
Chain of Responsibility: what does each handler do with a request it can't handle? Passes it to its next handler; the chain ends at the first handler that succeeds (or falls off the end → unhandled).
Mediator vs Observer? Both decouple, but Mediator centralizes specific coordination logic in a hub (many-to-many → star); Observer is generic one-to-many broadcast with no coordination logic.
Memento vs Command-based undo? Memento stores a full state snapshot (restore by replacing state); Command stores how to reverse a specific action . Use Memento when reversing is hard but snapshotting is cheap.
Visitor's core mechanism and trade-off? Double dispatch (element.accept(v) → v.visitX(element)). Easy to add new operations , hard to add new element types — the mirror of normal OOP.
What is the universal "trick" behind every behavioral pattern? Replace a hard-coded direct call or if/switch with a swappable/storable/queuable/notifiable object.
Template Method embodies which principle? Inversion of control / Hollywood Principle: "Don't call us, we'll call you" — the base method calls subclass hooks in a fixed order.
Design Patterns — Creational — make the objects that behavioral patterns then wire together.
Design Patterns — Structural — compose objects; Behavioral defines how composed objects interact .
SOLID Principles — Strategy/State/Command enact Open–Closed ; Visitor and Observer enact Dependency Inversion via interfaces.
Polymorphism — every behavioral pattern leans on dynamic dispatch.
Publish-Subscribe & Event-Driven Architecture — Observer scaled across processes/network.
Undo-Redo Systems — Command + Memento working together.
Swap object for if/switch
Communication and control flow
Intuition Hinglish mein samjho
Dekho, **behavioral design patter