Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Theodore Karropoulos
Theodore Karropoulos

Posted on • Edited on

     

A Deep Dive into the Strategy Design Pattern

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();}
Enter fullscreen modeExit fullscreen mode

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}}
Enter fullscreen modeExit fullscreen mode

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!");}}
Enter fullscreen modeExit fullscreen mode

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}}
Enter fullscreen modeExit fullscreen mode

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)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Hello I am Theodoros, am a Software engineer with passion on new technologies, basketball and sports in general!
  • Location
    Greece
  • Work
    Senior Software Engineer
  • Joined

More fromTheodore Karropoulos

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp