Behavioral Design Patterns in Java
1. Introduction
When we design software, objects often need to communicate with each other. Sometimes the communication is simple, but in larger systems it can get complicated and messy.
That’s where Behavioral Design Patterns come in.
They focus on:
- How objects interact
- How responsibilities are divided
- How communication can stay flexible and reusable
Think of them as rules that define how objects should collaborate.
2. The Different Behavioral Patterns
2.1 Chain of Responsibility
Imagine customer support: if your query is simple, the help desk solves it. If it’s more complex, it goes to a manager, and if still unresolved, it escalates further.
That’s exactly what this pattern does: passes a request through a chain of handlers until one handles it.
Example in Java: A logging framework where ErrorLogger, DebugLogger, and InfoLogger process logs based on severity.
2.2 Command Pattern
Think about pressing a button in an app. The button doesn’t know what happens when you press it; it just sends a command.
The command pattern encapsulates the request (like save, undo, redo) into an object, and the receiver executes it.
Commonly used in GUIs and remote control implementations.
2.3 Interpreter Pattern
This pattern is used to build a small language or grammar and evaluate it.
Example: A calculator that can interpret and evaluate 2 + 3 - 1.
It is not common in everyday Java projects but is useful in compilers, SQL parsing, or expression evaluators.
2.4 Iterator Pattern
You already use this in Java collections. The Iterator provides a way to traverse elements of a collection without exposing how they are stored.
Example:
Iterator it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
2.5 Mediator Pattern
Imagine an airport control tower. Planes do not communicate with each other directly; instead, they communicate via the control tower.
This pattern reduces direct dependencies and centralizes communication.
Example: A chatroom mediator between multiple users.
2.6 Memento Pattern
This pattern allows saving and restoring an object’s state without exposing its details.
Example: Undo functionality in a text editor. Each change can be saved as a snapshot and restored later.
2.7 Observer Pattern
When you subscribe to a YouTube channel, you get notified whenever the channel uploads a new video.
That is the observer pattern: a one-to-many relationship where the subject notifies its observers whenever its state changes.
Example in Java: Event listeners (ActionListener, PropertyChangeListener).
2.8 State Pattern
A vending machine behaves differently depending on its current state.
- If you insert a coin, it changes to the "HasCoin" state.
- If stock is empty, it changes to the "OutOfStock" state.
The state pattern allows objects to change their behavior dynamically as their internal state changes.
2.9 Strategy Pattern
When you want to sort a list, you can choose different sorting algorithms such as QuickSort, MergeSort, or BubbleSort.
The strategy pattern allows you to select an algorithm at runtime without changing the code using it.
Example: Payment methods such as PayPal, credit card, or UPI.
2.10 Template Method Pattern
Consider the process of making tea or coffee.
- Steps like boiling water are fixed.
- Adding tea leaves or coffee powder is the variable step.
This pattern defines the skeleton of an algorithm in a base class but allows subclasses to override specific steps.
Example: AbstractList in Java.
2.11 Visitor Pattern
Suppose you are designing a document editor with elements like text, images, and tables. Instead of modifying each element’s class whenever you need a new operation (like exporting or spell checking), you use a visitor.
The visitor defines the operation and visits each element. This allows you to add new operations without modifying the element classes.
3. Benefits of Behavioral Patterns
- Reduce tight coupling between objects.
- Make code more flexible and reusable.
- Distribute responsibilities more clearly.
- Many patterns (like Observer, Iterator) are already built into Java.
4. Challenges
- Can introduce additional abstraction, leading to more classes and more code.
- If overused, can increase system complexity.
- Some patterns (such as Visitor) require boilerplate across multiple classes.
5. Summary Table
Pattern | Real-Life Analogy | Purpose |
---|---|---|
Chain of Responsibility | Call center escalation | Pass request until someone handles it |
Command | Remote control button | Encapsulate request as object |
Interpreter | Calculator grammar | Interpret expressions |
Iterator | Next/Previous in playlist | Traverse collection safely |
Mediator | Air traffic control tower | Centralize communication |
Memento | Undo in text editor | Save/restore object state |
Observer | YouTube subscriptions | Notify dependents of state change |
State | Vending machine | Change behavior based on state |
Strategy | Choosing a payment method | Select algorithm at runtime |
Template Method | Making tea/coffee | Skeleton fixed, steps customizable |
Visitor | Tour guide visiting places | Add new operations without changing code |