Definition
Concept
Strategy: behavioral design pattern. Purpose: define a family of algorithms, encapsulate each, make them interchangeable. Clients select algorithm at runtime without altering code. Promotes open/closed principle, flexibility, reuse.
Scope
Applies to: object-oriented systems requiring dynamic algorithm selection or behavior changes. Useful for: sorting, compression, validation, routing strategies, etc.
Terminology
Strategy: algorithm interface. ConcreteStrategy: specific algorithm implementation. Context: object configured with a Strategy, delegates behavior to it.
Motivation
Problem
Hard-coded algorithms reduce flexibility. Conditional statements clutter code. Modification requires recompilation. Maintenance cost rises. Code duplication common.
Solution
Encapsulate algorithms in separate classes. Delegate execution to interchangeable Strategy objects. Context unaware of concrete algorithm details.
Benefits
Algorithm changes without context modification. Enhances maintainability, testability, and scalability. Supports runtime behavior changes.
Structure
Class Diagram
Context maintains reference to Strategy interface. ConcreteStrategy classes implement Strategy interface. Context delegates algorithm calls to Strategy.
UML Representation
+-----------------+ +------------------+| Context |<>-----| Strategy ||-----------------| |------------------|| - strategy:Strategy| | + algorithm() || + setStrategy() | +------------------+| + execute() | /_\+-----------------+ | +-------------+-------------+ | | +---------------+ +-------------+ | ConcreteStrategyA| | ConcreteStrategyB| +---------------+ +-------------+ | + algorithm() | | + algorithm() | +---------------+ +-------------+Communication
Context calls algorithm() on Strategy object. Strategy executes specific algorithm. Switching Strategy changes behavior dynamically.
Participants
Context
Maintains reference to Strategy object. Configured with ConcreteStrategy. Delegates algorithm execution to Strategy.
Strategy
Defines algorithm interface. Abstract class or interface declaring algorithm method(s).
ConcreteStrategy
Implements specific algorithm. Overrides Strategy interface methods.
Collaborations
Context-Strategy Interaction
Context delegates algorithm calls to Strategy. Context unaware of concrete implementation details.
Strategy Independence
Strategies operate independently. Context can switch Strategies without recompilation.
Client Configuration
Clients instantiate ConcreteStrategy and assign to Context. Enables dynamic behavior modification.
Consequences
Advantages
Improved flexibility: algorithms interchangeable at runtime. Simplifies unit testing. Reduces conditional code. Adheres to single responsibility and open/closed principles.
Disadvantages
Increased number of classes. Clients must understand different Strategies. Communication overhead via delegation.
Usage Considerations
Use when multiple variants of an algorithm exist. Avoid when algorithms are trivial or unlikely to change.
Implementation
Defining Strategy Interface
Declare common algorithm method(s). Can be abstract class or interface.
Implementing Concrete Strategies
Provide different algorithm variants. Override interface methods.
Context Class
Holds reference to Strategy. Provides setter for Strategy instance. Delegates algorithm calls.
Examples
Sorting Algorithms
Strategies: BubbleSort, QuickSort, MergeSort. Context: Sorter class delegates sorting to chosen algorithm.
Compression Techniques
Strategies: ZIP, RAR, GZIP compressors. Context: FileCompressor delegates compression method.
Payment Processing
Strategies: CreditCard, PayPal, Bitcoin processors. Context: PaymentHandler delegates payment method.
Advantages & Disadvantages
Advantages
| Advantages |
|---|
| Encapsulates algorithms for easy swapping |
| Reduces conditional branching in code |
| Promotes adherence to SOLID principles |
| Enhances maintainability and testing |
Disadvantages
| Disadvantages |
|---|
| Increases number of classes and objects |
| Clients must be aware of different strategies |
| Indirection may affect performance in critical systems |
Code Sample
Java Example
public interface Strategy { void execute();}public class ConcreteStrategyA implements Strategy { @Override public void execute() { System.out.println("Executing ConcreteStrategyA"); }}public class ConcreteStrategyB implements Strategy { @Override public void execute() { System.out.println("Executing ConcreteStrategyB"); }}public class Context { private Strategy strategy; public Context(Strategy strategy) { this.strategy = strategy; } public void setStrategy(Strategy strategy) { this.strategy = strategy; } public void executeStrategy() { strategy.execute(); }}public class Client { public static void main(String[] args) { Context context = new Context(new ConcreteStrategyA()); context.executeStrategy(); // Output: Executing ConcreteStrategyA context.setStrategy(new ConcreteStrategyB()); context.executeStrategy(); // Output: Executing ConcreteStrategyB }}Explanation
Strategy interface defines execute(). ConcreteStrategyA and B implement different behaviors. Context delegates executeStrategy() call to current Strategy. Client switches Strategies at runtime.
References
- E. Gamma, R. Helm, R. Johnson, J. Vlissides, Design Patterns: Elements of Reusable Object-Oriented Software, Addison-Wesley, 1994, pp. 293-311.
- F. Buschmann, R. Meunier, H. Rohnert, P. Sommerlad, M. Stal, Pattern-Oriented Software Architecture: A System of Patterns, Wiley, 1996, vol. 1, pp. 223-236.
- R.C. Martin, Clean Architecture: A Craftsman's Guide to Software Structure and Design, Prentice Hall, 2017, pp. 123-130.
- M. Fowler, Patterns of Enterprise Application Architecture, Addison-Wesley, 2003, pp. 299-310.
- S. Freeman, N. Pryce, Growing Object-Oriented Software, Guided by Tests, Addison-Wesley, 2009, pp. 150-160.