Definition
- Observer – defines a one-to-many dependency so when a subject changes, all registered observers are notified automatically.
- Command – packages an action as an object with
execute()andundo(), enabling queuing, logging, and reversal. - Iterator – exposes elements of a collection sequentially without revealing its internals.
- State – lets an object change behaviour when its internal state changes, as if it changed class.
- Template Method – defines the skeleton of an algorithm in a base method and lets subclasses fill specific steps.
- Visitor – adds new operations to a stable set of element classes without modifying them.
- Mediator – centralises complex communication between objects so they do not reference each other directly.
- Memento – captures and restores an object's state without exposing its internals.
At National Bank of India: Observer is the alert system that tells audit, SMS, and the dashboard when a transfer completes. Command is writing each banking instruction on a slip that can be queued, logged, and reversed. Iterator is flipping through a passbook one entry at a time. State is an account behaving differently when ACTIVE versus FROZEN. Template Method is the fixed settlement procedure where only one step changes per instrument. Visitor is the auditor who visits every account and performs a new check without changing the accounts. Mediator is the dealing desk that coordinates traders. Memento is a saved snapshot of an account you can roll back to.
Understanding the Concepts
What is the Observer pattern?
Observer defines a one-to-many dependency: when the subject changes, all registered observers are notified. The subject exposes subscribe and unsubscribe methods and holds a list of observers.
package com.bank.observer;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
public class TransferPublisher {
private final List<Consumer<TransferEvent>> listeners = new ArrayList<>();
public void subscribe(Consumer<TransferEvent> listener) {
listeners.add(listener);
}
public void publish(TransferEvent event) {
listeners.forEach(l -> l.accept(event));
}
}
public record TransferEvent(String fromId, String toId, BigDecimal amount) {}
publisher.subscribe(e -> System.out.println("AUDIT: " + e));
publisher.subscribe(e -> System.out.println("SMS to Priya: Transfer of INR " + e.amount()));
publisher.publish(new TransferEvent("SAV2001", "SAV3002", new BigDecimal("50000")));
AUDIT: TransferEvent[fromId=SAV2001, toId=SAV3002, amount=50000]
SMS to Priya: Transfer of INR 50000
What is the Command pattern?
Command encapsulates a request as an object with an execute method and often an undo. The invoker triggers commands without knowing what they do.
package com.bank.command;
import java.math.BigDecimal;
public interface Command {
void execute();
void undo();
}
public class DebitCommand implements Command {
private final Account account;
private final BigDecimal amount;
public DebitCommand(Account account, BigDecimal amount) {
this.account = account;
this.amount = amount;
}
@Override
public void execute() { account.debit(amount); }
@Override
public void undo() { account.credit(amount); }
}
Command cmd = new DebitCommand(rajeshAccount, new BigDecimal("10000"));
cmd.execute(); // debits 10000
cmd.undo(); // credits 10000 back
What is the Iterator pattern?
Iterator provides sequential access to a collection without exposing its structure. Every Java collection returns one.
package com.bank.iterator;
import java.util.Iterator;
import java.util.List;
public class TradeIteratorDemo {
public static void main(String[] args) {
List<String> trades = List.of("BUY RELIANCE", "SELL HDFC", "BUY ICICI");
Iterator<String> it = trades.iterator();
while (it.hasNext()) {
System.out.println("Processing: " + it.next());
}
}
}
Processing: BUY RELIANCE
Processing: SELL HDFC
Processing: BUY ICICI
What is the State pattern?
State lets an object alter its behaviour when its internal state changes. The object delegates to a state object, and each state class implements the behaviour differently.
package com.bank.state;
import java.math.BigDecimal;
public interface AccountState {
void withdraw(AccountContext ctx, BigDecimal amount);
}
public class ActiveState implements AccountState {
@Override
public void withdraw(AccountContext ctx, BigDecimal amount) {
ctx.setBalance(ctx.getBalance().subtract(amount));
System.out.println("Withdrawn INR " + amount);
}
}
public class FrozenState implements AccountState {
@Override
public void withdraw(AccountContext ctx, BigDecimal amount) {
throw new IllegalStateException("Account is frozen, cannot withdraw");
}
}
AccountContext account = new AccountContext(new BigDecimal("100000"));
account.setState(new ActiveState());
account.withdraw(new BigDecimal("5000")); // works
account.setState(new FrozenState());
account.withdraw(new BigDecimal("5000")); // throws IllegalStateException
What is the Template Method pattern?
Template Method defines the invariant steps of an algorithm in a base method and defers variable steps to subclasses.
package com.bank.template;
import java.math.BigDecimal;
public abstract class SettlementTemplate {
// Template method: fixed skeleton
public final void settle(String tradeId, BigDecimal amount) {
validate(tradeId);
execute(tradeId, amount); // varies by instrument
record(tradeId, amount);
}
private void validate(String tradeId) {
System.out.println("Validating trade: " + tradeId);
}
protected abstract void execute(String tradeId, BigDecimal amount);
private void record(String tradeId, BigDecimal amount) {
System.out.println("Recording settlement of INR " + amount);
}
}
public class EquitySettlement extends SettlementTemplate {
@Override
protected void execute(String tradeId, BigDecimal amount) {
System.out.println("Settling equity trade " + tradeId
+ " for INR " + amount);
}
}
Validating trade: TRD001
Settling equity trade TRD001 for INR 250000
Recording settlement of INR 250000
What is the Visitor pattern?
Visitor adds a new operation over a set of element classes without modifying them. Each element accepts a visitor that performs the operation.
package com.bank.visitor;
import java.math.BigDecimal;
public interface AccountVisitor {
void visit(SavingsAccount sa);
void visit(CurrentAccount ca);
}
public class InterestReportVisitor implements AccountVisitor {
@Override
public void visit(SavingsAccount sa) {
BigDecimal interest = sa.getBalance()
.multiply(new BigDecimal("0.04"));
System.out.println("Savings interest: INR " + interest);
}
@Override
public void visit(CurrentAccount ca) {
System.out.println("Current accounts earn no interest");
}
}
SavingsAccount sa = new SavingsAccount(new BigDecimal("500000"));
sa.accept(new InterestReportVisitor());
Savings interest: INR 20000
What is the Mediator pattern?
Mediator centralises communication between many objects so they do not reference each other directly.
package com.bank.mediator;
import java.util.ArrayList;
import java.util.List;
public class TradingDeskMediator {
private final List<Trader> traders = new ArrayList<>();
public void register(Trader trader) { traders.add(trader); }
public void broadcast(String message, Trader sender) {
traders.stream()
.filter(t -> t != sender)
.forEach(t -> t.receive(message));
}
}
What is the Memento pattern?
Memento captures and restores an object's state without exposing its internals.
package com.bank.memento;
import java.math.BigDecimal;
public class AccountMemento {
private final BigDecimal balance;
private final String status;
AccountMemento(BigDecimal balance, String status) {
this.balance = balance; this.status = status;
}
BigDecimal getBalance() { return balance; }
String getStatus() { return status; }
}
public class BankAccount {
private BigDecimal balance;
private String status;
public AccountMemento save() {
return new AccountMemento(balance, status);
}
public void restore(AccountMemento m) {
this.balance = m.getBalance();
this.status = m.getStatus();
}
}
AccountMemento snapshot = account.save();
account.withdraw(new BigDecimal("50000"));
// Something went wrong, roll back
account.restore(snapshot);
What should a senior engineer know?
In modern Java several of these patterns shrink to lambdas. Command is often just a Runnable. Observer listeners are lambdas. Iterator is hidden inside the for-each loop and streams. The pattern intent still guides the design even when the actual Java form is a single line.
// Command as Runnable
Runnable cmd = () -> account.debit(new BigDecimal("10000"));
cmd.run();
// Observer as lambda
publisher.subscribe(e -> log.info("Transfer: " + e));
// Iterator hidden in streams
trades.stream().forEach(t -> process(t));
Recognising both the intent and the lightweight form is what shows these patterns are applied the way they really appear in production.
Visual Overview
Eight Behavioral Patterns
─────────────────────────
Observer: Subject ──notify──→ [Observer A, Observer B, Observer C]
Command: Invoker ──execute──→ Command ──→ Receiver
Iterator: Client ──next()──→ Iterator ──→ Collection
State: Context ──delegate──→ [Active | Frozen | Closed]
Template: Base.settle() { validate(); execute(); record(); }
↑ subclass fills this step
Visitor: Element.accept(visitor) ──→ visitor.visit(element)
Mediator: Trader A ──→ Desk ──→ Trader B, Trader C
Memento: Account ──save()──→ Memento ──restore()──→ Account
Key Takeaway
Behavioral patterns describe how objects communicate and divide responsibility. Observer defines a one-to-many relationship where a subject notifies all its subscribers on a change, which is how a completed transfer triggers audit, SMS, and dashboard reactions. Command packages an action as an object with execute and undo, so operations can be queued, logged, replayed, or reversed. Iterator gives sequential access to a collection without exposing its internals. State lets an object change behaviour when its internal state changes, replacing sprawling conditionals with clean state classes.
Template Method defines the fixed skeleton of an algorithm and lets subclasses fill the varying steps, which is how a settlement always validates, executes, and records while only the execute step changes per instrument. Visitor adds operations to stable element classes without modifying them. Mediator centralises many-to-many communication so objects do not reference each other directly. And Memento captures and restores an object's state for undo and checkpoints.
In the transaction engine at National Bank of India, these appear together: Rajesh publishes a transfer event to many observers, models debit and credit as reversible commands, uses State so a frozen account rejects withdrawals, and uses a settlement template so the procedure shape is fixed while the instrument-specific step varies.
The senior point is that in modern Java several of these shrink to lambdas: a Command is often just a Runnable, Observer listeners are lambdas, and Iterator is hidden inside streams. The pattern intent still guides the design even when the actual Java form is a single line, and recognising both the intent and the lightweight form is what shows real production understanding.
Remember one sentence: behavioral patterns govern how objects communicate, and the eight classics cover notification, action packaging, traversal, state-driven behaviour, algorithm skeletons, operation extension, coordination, and state snapshots.
---