CHAPTER 14
Intermediate
Strategy Pattern
Updated: May 16, 2026
30 min read
# CHAPTER 14
Strategy Pattern
1. Introduction
Imagine you are building a Google Maps clone. Initially, your app only calculates routes for Cars. YourcalculateRoute() method works perfectly. A month later, you add Walking routes. You add an if statement. Then you add Bicycles. Then Public Transit. Your calculateRoute() method is now a terrifying, 2,000-line monster of nested if/else statements. If a developer breaks the Bicycle logic, the entire routing system crashes. This violates the Open/Closed Principle entirely. The Strategy Pattern is the architectural cure for algorithmic bloat. In this chapter, we will master the Strategy Pattern, learning how to extract dynamic algorithms into interchangeable classes, allowing our objects to swap behaviors instantly at runtime.
2. Learning Objectives
By the end of this chapter, you will be able to:-
Identify the algorithmic bloat caused by massive
switchorif/elsestatements.
- Define the intent and structure of the Strategy Pattern.
- Encapsulate families of algorithms into interchangeable Strategy classes.
- Understand how to swap object behavior dynamically at runtime (Context switching).
- Compare the Strategy Pattern with the State Pattern.
3. The Core Concept
The Strategy pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it.-
The Context: The main object the user interacts with (e.g., the
Navigatorclass).
-
The Strategy Interface: The contract that all algorithms must follow (e.g.,
RouteStrategyinterface with abuildRoute()method).
-
The Concrete Strategies: The encapsulated algorithms (e.g.,
CarStrategy,BikeStrategy).
4. Swapping at Runtime
The magic of the Strategy pattern is dynamic behavior. Instead of hardcoding the algorithm inside theNavigator, the Navigator holds a reference to a RouteStrategy object. When the user clicks the "Bicycle" icon, the app calls $navigator->setStrategy(new BikeStrategy()). The Navigator doesn't know *how* the bike route is calculated; it just delegates the work to the currently active strategy.
5. Strategy vs. Decorator
They both use composition, but have different intents.- Decorator: *Adds* behavior to an object, wrapping it in new features.
- Strategy: *Changes* the gut behavior of an object by swapping out its core algorithm.
6. UML Diagram
*Strategy Structure*
text
7. Code Example (PHP)
Let's build a dynamic Payment Processing system.
php
8. Best Practices
-
Eliminate Switch Statements: The ultimate "code smell" indicating you need a Strategy Pattern is a massive
switchstatement based on a type variable (e.g.,switch ($type) { case 'A': doA(); case 'B': doB(); }). Replace the switch statement by making A and B separate Strategy classes.
9. Common Mistakes
-
Over-Engineering Trivial Logic: If you have an
if/elsestatement that calculates a 5% tax vs a 10% tax, do not create aFivePercentTaxStrategyclass. The Strategy pattern introduces multiple new files and interfaces. It should only be used when the algorithms are complex, highly volatile, and require complete decoupling.
10. Mini Project: Build an Image Compression Tool
-
1.
Context: Create an
ImageSaverclass.
-
2.
Strategy: Create a
CompressionStrategyinterface with acompress($file)method.
-
3.
Concrete Strategies: Create
JpegCompression(lossy) andPngCompression(lossless).
- 4. Action: Write a script that loads an image, sets the Strategy to Jpeg, saves it, then dynamically swaps the strategy to Png and saves it again.
11. Practice Exercises
- 1. Define the primary architectural code smell (hint: large control structures) that indicates a codebase desperately needs to be refactored using the Strategy pattern.
- 2. Explain how the Strategy pattern enables an application to change its core behavior dynamically at runtime without requiring a reboot or a new object instantiation.
12. MCQs with Answers
Question 1
A developer is tasked with building a sorting module that needs to switch between QuickSort, MergeSort, and BubbleSort depending on the size of the array. To avoid a massive if/else block and adhere to the Open/Closed Principle, which pattern should they deploy to encapsulate these algorithms?
Question 2
In the Strategy Pattern, the class that holds the reference to the active algorithm and delegates the execution to it (e.g., the ShoppingCart class) is formally known as the:
13. Interview Questions
- Q: Compare and contrast the Strategy Pattern with the State Pattern. Structurally they are nearly identical; how do their architectural intents differ?
-
Q: Walk me through a refactoring process. You inherit a massive 3,000-line class with a
switchstatement that handles 10 different types of data export (CSV, XML, JSON). Explain exactly how you would use the Strategy pattern to break this God Class apart.
- Q: Explain how the Strategy pattern heavily relies on the SOLID "Dependency Inversion Principle."
14. FAQs
Q: How does the Context pass data to the Strategy? A: Two ways. 1) The Context passes exactly the variables the Strategy needs as arguments (execute($amount)). 2) The Context passes *itself* to the Strategy (execute($this)), allowing the Strategy to query the Context for whatever data it needs. The first is more decoupled; the second is more flexible.
15. Summary
In Chapter 14, we cured algorithmic bloat. We identified that massive, hardcodedswitch statements are fragile, violation-heavy anti-patterns. By deploying the Strategy Pattern, we encapsulated volatile, changing algorithms into isolated, easily testable classes. We established a Context capable of seamlessly swapping its internal logic at runtime via simple interface injection. This architectural decoupling ensures that adding new features (like a new payment gateway or a new routing map) requires zero modification to our core application logic.