Strategy Pattern

Reading Time: 3 minutes

strategy-post

What is Strategy Pattern?

Strategy pattern is a commonly used behavioural pattern1. Strategy Pattern is mostly a way to change the behaviour of an algorithm at runtime.

The strategy pattern:

  • defines a family of algorithms,
  • encapsulates each algorithm, and
  • makes the algorithms interchangeable within that family.

Consequences

Think twice before implementing this pattern. You have to be sure your need is to change an algorithm frequently. You have to clearly anticipate the future, otherwise, this pattern will be more expensive than a basic implementation.

  • + Greater flexibility, reuse
  • + Can change algorithms dynamically
  •  Strategy creation & communication overhead
  •  Expensive to create
  • This pattern can be expensive to maintain. If the representation of a class often changes, you will have lots of refactoring.

Give me EXAMPLES!

Imagine that you are going to validate data. With strategy pattern, you are able to use different algorithms based on the type of data, source of the data, timestamp of the data or discriminating factors at runtime. The algorithms are called “strategies” in this case. Pretty obvious I would say.

Another example is changing Internet Protocol Suite at runtime. Think of a method for connecting and sending network data. Maybe in some cases you would prefer to connect and send UDP datagrams, maybe in other situations where performance was less of a factor you would send using TCP/IP. You can decide which to use at runtime with strategy pattern.

The strategies are encapsulated seperately from the validating object, meaning that we can use the same strategies on different areas of the system. This enforces modularity2, cohesion3, orthogonality4 and every other best programming practices.

Capture
UML of Strategy Pattern

Code Example

Imagine we are developing a strategy game including Infantries and Tanks. They can move() and fire(). For fire() function, we can use normal polymorphism/inheritance since firing will be different for any unit(Infantries fire short distance light bullets, Tanks fire heavy long-distance round), and it won’t change during the game.

Then think of terrain. Imagine there are two types of terrain; swamp and road. Infantries and Tanks will move different on each terrain type. That means we actually need to change the behaviour of move() function at runtime because the terrain might change while they move.

Now, when any Unit move inside a Swamp, we call:

And as soon it goes to a Road, we do:

Now we’re able to change how far away our units move depending on the Terrain, and we don’t need to rewrite in any of the subclasses.

  1. Behavioral patterns are design patterns that identify common communication patterns between objects and realize these patterns. By doing so, these patterns increase flexibility in carrying out this communication.
  2. Modularity is a measurement of how well divided into chunks your code is. Very roughly, if different parts of your system can be swapped out without breaking unrelated stuff, the higher your modularity is. It’s about building complex things from simple ones, instead of building a big complex thing from the get-go.
  3. Cohesion refers to the degree to which the elements inside a module belong together.
  4. Orthogonality is the property that means “Changing A does not change B”. An example of an orthogonal system would be a radio, where changing the station does not change the volume and vice-versa.

Leave a Reply