Hello! Welcome to the final lesson in our module on behavioral design patterns.
In our previous lessons, you've explored a powerful set of patterns, each designed to manage responsibilities and algorithms within a system. We covered Strategy, State, Template Method, Visitor, Memento, and even the high-level MVC architectural pattern. Now, it's time to bring it all together.
A common challenge in system design interviews (and in real-world development) isn't just knowing what each pattern is, but knowing when to use each one. Many patterns can seem similar at first glance. Today's lesson focuses on exactly that. Our learning outcome is to compare responsibility and algorithm-focused behavioral patterns to select the best fit. We will analyze their intents, structures, and trade-offs to build a mental framework for making design decisions.
A Visual Recap of Behavioral Patterns
To start, let's look at a quick visual summary of the patterns we'll be discussing. This will help refresh your memory of their core purpose.

Our goal is to move beyond these one-line descriptions and understand the subtle but crucial differences that make one pattern more suitable than another in a specific context.
The "Algorithm Variation" Trio: Strategy, State, and Template Method
These three patterns are often confused because they all provide ways to alter an object's behavior or algorithm. Let's dissect their differences.
Strategy vs. State
Both patterns use composition to change a context object's behavior by delegating to a separate helper object. Structurally, they can look almost identical, with a context class holding a reference to an interface, and concrete classes implementing that interface. The difference lies entirely in their intent.
Let's watch a short video that directly compares these two patterns.
The Strategy Pattern Explained and Implemented in Java | Behavioral Design Patterns | Geekific
This video from Geekific provides an excellent, concise comparison between the Strategy and State patterns, highlighting their different goals despite their structural similarities.
Watch the section from 05:11 to 06:34. Focus on the key differences mentioned: The independence of strategies versus the potential dependence and transitions between states. Whether the goal is to accomplish the same thing in different ways (Strategy) or do different things based on the state (State).
To summarize and expand on the video's points:
| Aspect | Strategy Pattern | State Pattern |
|---|---|---|
| Intent | Encapsulates a family of algorithms and makes them interchangeable. It's about how a task is performed. | Allows an object to alter its behavior when its internal state changes. It's about what an object can do in a given state. |
| Example | Different payment methods (Credit Card, PayPal) to complete a purchase. The goal (purchase) is the same. | A media player's buttons behaving differently depending on whether it's in the Playing, Paused, or Stopped state. The behavior changes entirely. |
| State Management | The client typically decides which strategy to use and passes it to the context. | State transitions are often managed internally, either by the context or by the state objects themselves. The client usually doesn't set the state directly after initialization. |
| Coupling | Concrete strategies are independent and unaware of each other. | Concrete states are often coupled because they need to instantiate and transition to other states. |
Strategy vs. Template Method
Now, let's compare Strategy with the Template Method pattern. Both are used to vary parts of an algorithm, but they achieve this in fundamentally different ways.
This document clearly lays out the distinctions between Strategy and Template Method, which boil down to a classic design choice: composition versus inheritance.
Please read the 'Relations with Other Patterns' subsection under the 'STRATEGY' pattern. Focus on the comparison with Template Method. It states: 'Template Method is based on inheritance... Strategy is based on composition... Template Method works at the class level... Strategy works on the object level'. Also, review the same comparison in the 'TEMPLATE METHOD' section to reinforce this.
This comparison highlights a fundamental principle in object-oriented design:
- Template Method uses inheritance. It defines a fixed skeleton for an algorithm in a base class and lets subclasses override specific steps. This is a static relationship defined at compile time.
- Strategy uses composition. It defines an entire algorithm as an object. The context object is configured with a strategy object, which can be swapped out at runtime. This is a dynamic relationship.
Choose Template Method when you have a mostly invariant algorithm with a few customizable steps. Choose Strategy when you need to switch between completely different algorithms at runtime.
The "Responsibility & Request Handling" Trio: Command, Visitor, and Chain of Responsibility
This group of patterns offers different ways to decouple the object that initiates a request from the object(s) that process it.
Command vs. Strategy
This is another common point of confusion. Both patterns encapsulate some logic in an object.
The Command and Strategy patterns can seem similar because they both parameterize an object with an action. However, their intents are very different. Let's read a clear comparison.
Read the 'Relations with Other Patterns' subsection under the 'Command' pattern, focusing on the comparison with Strategy. Then, read the same comparison under the 'Strategy' pattern. Pay attention to the core difference: Command turns a request into an object (for queuing, undo, etc.), while Strategy provides different ways of doing the same thing.
Here’s the breakdown:
- Command turns a request into a stand-alone object. This is useful when you want to parameterize objects with actions, queue requests, log them, or support undoable operations. The command object encapsulates the action and the receiver that will perform it.
- Strategy is about providing different ways to perform a single task. The context executes the strategy to get a result.
Think of it this way: a Strategy object computes something for you; a Command object does something for you. A SortingStrategy will sort a list. A SaveDocumentCommand will save a document.
Command, Visitor, and Chain of Responsibility
These three patterns provide powerful, but distinct, ways to manage how operations are dispatched and executed.
-
Command: As we just saw, it decouples the sender from the receiver. The sender (invoker) just needs to know how to
execute()a command; it doesn't know what the command does or who the receiver is. This is a one-to-one decoupling, at a high level. -
Chain of Responsibility: Use this pattern when you want to give more than one object a chance to handle a request. It creates a chain of handler objects. The sender gives the request to the first handler in the chain, which either processes it or passes it to the next handler. This is useful when the handler isn't known upfront or when multiple handlers might need to act on a request. A classic example is a series of servlet filters in a web application, where each filter can process an HTTP request.
-
Visitor: This pattern is unique. You use it when you need to perform an operation on the elements of a complex object structure (e.g., a tree) without changing the classes of the elements on which it operates. It lets you define a new operation without changing the classes of the elements to be operated on. It works by using a technique called double dispatch. The
elementcalls avisit()method on thevisitor, passing itself as an argument (visitor.visit(this)). This allows the visitor to execute code specific to that element's class. It's ideal when you have a stable set of data classes but need to frequently add new functions that operate on them (e.g., adding export-to-XML, export-to-JSON, or validation logic to a set of shape classes).
A Decision-Making Framework
When faced with a design problem, ask yourself these questions to guide your choice of pattern:
| If your problem is... | Consider using... | Because... |
|---|---|---|
| Choosing between different algorithms to complete the same task at runtime. | Strategy | It uses composition to let you swap entire algorithms dynamically. |
| An object's behavior must change dramatically based on its internal state. | State | It links behavior directly to state, making the object appear to change its class. |
| You have an algorithm with a fixed structure but variable implementation steps. | Template Method | It uses inheritance to define a skeleton and lets subclasses fill in the blanks. |
| You need to queue, undo, or log operations, or decouple the "what" from the "who". | Command | It encapsulates a request as an object, decoupling the invoker from the receiver. |
| You have a stable object structure and need to add new operations without modifying the existing classes. | Visitor | It separates algorithms from the objects they operate on, allowing new functionality to be added easily. |
| A request could be handled by one of several objects, and you don't know which one in advance. | Chain of Responsibility | It passes a request along a chain of handlers until one processes it. |
Test your understanding!
For each scenario, which behavioral pattern would be most appropriate and why?
- You are building a shipping cost calculator. The cost needs to be calculated differently based on the chosen shipping provider (e.g., FedEx, UPS, DHL). The user can select the provider at checkout.
- You are designing a workflow system where a document must go through several approval steps: first by a manager, then by a director, and finally by legal. Each role can approve or reject the document.
- You are creating a drawing application. You need to implement an "undo" feature that allows users to revert their last 10 actions (e.g., drawing a line, adding text, changing a color).
- You are implementing a document processing tool. The core algorithm involves three steps:
open document,extract text,close document. The logic forextract textdiffers for PDF, DOCX, and TXT files, but the open/close steps are the same.
Show answer
- Strategy Pattern. The core task (calculating shipping cost) is the same, but the algorithm for doing so changes based on the selected provider. Each provider's calculation logic can be encapsulated in a separate
ShippingStrategyclass. - Chain of Responsibility Pattern. The approval request is passed along a chain of handlers (manager, director, legal). Each handler decides whether to process the request (approve/reject) or pass it to the next person in the chain.
- Command Pattern. Each user action can be encapsulated as a command object (e.g.,
DrawLineCommand,AddTextCommand). These command objects can be stored in a history list. The "undo" feature would simply pop the last command from the list and execute itsundo()method. - Template Method Pattern. The overall algorithm structure is fixed. You can create an abstract
DocumentProcessorbase class with a template method that callsopen(),extract(), andclose(). Theextract()method would be abstract, forcing subclasses likePdfProcessor,DocxProcessor, andTxtProcessorto provide their specific implementations.
Conclusion
You've now reached the end of our deep dive into behavioral patterns. You've not only learned what each pattern does but, more importantly, how to distinguish between them.
Key Takeaways:
- Intent is King: The most crucial factor in choosing a pattern is understanding the specific problem you are trying to solve. Structural similarity can be misleading.
- Composition vs. Inheritance: Patterns like Strategy (composition) and Template Method (inheritance) offer different trade-offs between runtime flexibility and compile-time structure.
- Decoupling Senders and Receivers: Patterns like Command, Chain of Responsibility, and Observer provide different mechanisms for decoupling objects, leading to more flexible and maintainable systems.
This knowledge is not just theoretical. It is the practical toolkit you will use to build robust, maintainable, and scalable software.
In our next module, we will begin The Low-Level Design Process. We will shift from learning individual patterns to applying them in a structured way to solve complete LLD problems, just as you would in an interview. You will learn how to go from a vague problem statement to a detailed class diagram, making conscious design choices and justifying them using the principles and patterns you've mastered.