The Strategy pattern is a behavioral design pattern that allows you to define a family of algorithms or behaviors, encapsulate each one as a separate class, and make them interchangeable at runtime. The pattern enables you to select the algorithm or behavior dynamically based on the specific context or requirements.
To put it simply, the strategy pattern gives you the flexibility to choose the right strategy for a task, just like selecting the most suitable tool from a toolbox. This approach makes your code more modular and adaptable, as you can plug in different strategies without making major changes to your overall program.
Problem
Imagine you're a chef and you have different ways to cook a dish. You can bake, fry, or steam the food. Each cooking method represents a strategy. Now, instead of hard-coding a specific cooking method in your recipe, you can use the strategy pattern. You define an interface called "CookingStrategy" with a common method, let's say "Cook()", and create separate classes for each cooking method that implement this interface (e.g., "BakingStrategy", "FryingStrategy", "SteamingStrategy").
At runtime, based on the recipe or customer's preference, you can dynamically select the appropriate cooking strategy. You can switch between baking, frying, or steaming without modifying the recipe code. This flexibility allows you to add new cooking strategies in the future without affecting the existing code.
Chef code example
To start, we need to create an interface called ICookingStrategy, which will act as our Strategy interface. This interface will declare a common method Cook() that represents the cooking action. It serves as a contract that all cooking strategies must adhere to.
// Define the CookingStrategy interfacepublicinterfaceICookingStrategy{voidCook();}
The next step is to create multiple classes that implement the ICookingStrategy interface. Each implementation will provide specific instructions for a particular cooking method within its Cook() method. For example, we can have a BakingStrategy class that contains instructions on how to bake the dish, a FryingStrategy class for frying, and a SteamingStrategy class for steaming.
// Implement the BakingStrategypublicclassBakingStrategy:ICookingStrategy{publicvoidCook(){Console.WriteLine("Baking the dish...");// Add specific instructions for baking}}// Implement the FryingStrategypublicclassFryingStrategy:ICookingStrategy{publicvoidCook(){Console.WriteLine("Frying the dish...");// Add specific instructions for frying}}// Implement the SteamingStrategypublicclassSteamingStrategy:ICookingStrategy{publicvoidCook(){Console.WriteLine("Steaming the dish...");// Add specific instructions for steaming}}
Next, we'll introduce a Chef class that makes use of the strategy pattern. This class features a private member named _cookingStrategy, which is of type ICookingStrategy. This member holds the currently selected cooking strategy. With the SetCookingStrategy() method, we can specify the desired cooking strategy. To initiate the cooking process, we invoke the CookDish() method. It triggers the Cook() method of the selected strategy to cook the dish, and also handles any additional steps required for dish preparation.
// Chef class that utilizes the strategy patternpublicclassChef{privateICookingStrategy_cookingStrategy;// Set the cooking strategypublicvoidSetCookingStrategy(ICookingStrategycookingStrategy){_cookingStrategy=cookingStrategy;}// Cook the dish using the selected strategypublicvoidCookDish(){Console.WriteLine("Preparing the dish...");_cookingStrategy.Cook();// Additional steps for dish preparationConsole.WriteLine("Dish is ready!");}}
Finally, we can utilize the pattern in the following manner
classProgram{staticvoidMain(string[]args){// Create a Chef instanceChefchef=newChef();// Create different cooking strategiesICookingStrategybakingStrategy=newBakingStrategy();ICookingStrategyfryingStrategy=newFryingStrategy();ICookingStrategysteamingStrategy=newSteamingStrategy();// Set the baking strategychef.SetCookingStrategy(bakingStrategy);chef.CookDish();// The dish will be baked// Set the frying strategychef.SetCookingStrategy(fryingStrategy);chef.CookDish();// The dish will be fried// Set the steaming strategychef.SetCookingStrategy(steamingStrategy);chef.CookDish();// The dish will be steamed}}
When to use the strategy pattern
Strategy pattern is a good choice when you need flexibility and modularity in choosing and swapping out different algorithms or behaviors at runtime.
Pros and cons of using the strategy pattern
✔️ Improved code organization
✔️ Flexibility and extensibility
✔️ Code reusability
✔️ Separation of concerns
❌ Increases the complexity of the code
❌ Potential performance overhead
❌ Increased number of classes
Top comments(0)
For further actions, you may consider blocking this person and/orreporting abuse