Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When and why should the Strategy Pattern be used?

When would the Strategy Pattern be used?

I see client code snippets like this:

  class StrategyExample {      public static void main(String[] args) {          Context context;          // Three contexts following different strategies         context = new Context(new ConcreteStrategyAdd());         int resultA = context.executeStrategy(3,4);          context = new Context(new ConcreteStrategySubtract());         int resultB = context.executeStrategy(3,4);          context = new Context(new ConcreteStrategyMultiply());         int resultC = context.executeStrategy(3,4);      }  }  

and it looks like you could just refactor it to this:

  class StrategyExample {      public static void main(String[] args) {          // Three contexts following different strategies         int resultA =new ConcreteStrategyAdd().execute(3,4);         int resultB =new ConcreteStrategySubtract().execute(3,4);         int resultC =new ConcreteStrategyMultiply().execute(3,4);     }  }  

The first section of code was taken directly from the wikipedia page. One big difference is the context goes away, but it wasn't doing anything in the example anyway. Maybe someone has a better example where Strategy makes sense. I usually like design patterns but this one seems to add complexity without adding usefulness.

like image 744
User1 Avatar asked Nov 10 '09 20:11

User1


People also ask

Why do we need Strategy pattern?

In computer programming, the strategy pattern (also known as the policy pattern) is a behavioral software design pattern that enables selecting an algorithm at runtime. Instead of implementing a single algorithm directly, code receives run-time instructions as to which in a family of algorithms to use.

What is the best reason to use a design pattern?

Why use a design pattern? The usefulness of using a design pattern is obvious. The design pattern can accelerate the development process. It provides proven development paradigms, which helps save time without having to reinvent patterns every time a problem arises.

What is the use of a Strategy pattern give an example where it can be used?

A good example of strategy pattern would be in a game where we can have different characters and each character can have multiple weapons to attack but at a time can use only one weapon.

What is pattern strategy?

A pattern-based strategy is essentially the process of a business looking for signs of change, in order to be responsive and reactive at a macro level. Gartner defines pattern-based strategy as the discipline that enables business leaders to inquire, expand, examine and utilize new trade and marketing patterns.


2 Answers

The problem with toy examples such as this is that it is often easy to miss the point. In this case, the code could indeed be just implemented as you have shown. In a strategy pattern, the main value is in being able to switch out different implementations for different situations.

The example you have is only illustrating the objects in the pattern and the interactions between them. Imagine instead that you had a component that renders graphs for a website depending on whether it was a desktop or a smartphone on the other end you would have some code that would detect the type of browser the create and set the strategy on another component that could use the strategy object in some complex code that would not need to be duplicated and would do the work in both situations leaving the details of the actual drawing of the graph to the appropriate strategy object:

interface GraphStrategy {     Image renderGraph(Data graphData); }  class BigGraphStrategy implements GraphStrategy {     ... }  class SmallGraphStrategy implements GraphStrategy {     ... } 

Then in some other code:

GraphStrategy graphStrategy;  if (phoneBrowser == true) {      graphStrategy = new SmallGraphStrategy(); } else {     graphStrategy = new BigGraphStrategy(); } 

The rest of your application code can then just use graphStrategy.renderGraph() without having to know whether full or small image rendering is being performed.

like image 193
Tendayi Mawushe Avatar answered Sep 22 '22 21:09

Tendayi Mawushe


Areas that come to mind:

  • A resource allocator. In manual resource management, this might be minimizing the time it takes for the resource to allocate, or minimizing fragmentation. Each strategy here has an "Allocate" method that has the same interface, with the user making a decision about which strategy to use based on what they are trying to optimize.
  • A method for connecting and sending network data. Maybe in some cases you would prefer to connect and send UDP datagrams, maybe in other situatinos where performance was less of a factor you would send using TCP/IP.
  • Data formatting/serialization strategy. Allow the code to decide whether an object should be serialized with Json or with Xml. Maybe one for machines, and the other for human-readable situations. Both strategies have a "Serialize" method which takes an object. Each serializes differently.

The theme is that the decision on whether to do something one way or another way is dependent on situational factors, and you or your code would choose the correct strategy based on the situation.

Now why would this be more useful than something like:

void DoIt() {     if (... situation1...)     {        DoA()     }     else     {        DoB();     } } 

The reason is sometimes you want to just make the decision once and forget about it. The other important theme to strategy pattern is that you decouple the decision about which strategy to use from the code that needs to execute the strategy.

DoItStrategy MakeDoItStrategy() {      if (... situation1...)      {            return new DoItStrategyA();      }      else      {            return new DoItStrategyB();      } } 

In the last example you can just just store the strategy, passing it as just another object that implements the strategy interface. For those executing the strategy, they simply have a way to perform an action. They don't know what the inner workings are under the hood, only that the interface will be satisfied. The users of the strategy shouldn't need to know why we made a decision. They just need to do an action. We make a decision once and passed the strategy to the classes that use the strategy.

For example, consider the case where we make a program-wide decision, based on a given network configuration, to connect and send data to a remote hosts with UDP. Instead of each user of the network interface needing to know the logic to make the decision (the "DoIt" function above), we can create the UDP strategy upfront and pass it to everyone who needs to send network data. This strategy then implements a simple interface with the same end result - data gets from A to B.

like image 34
Doug T. Avatar answered Sep 18 '22 21:09

Doug T.