Design Patterns: Strategy Pattern

henriguy profile image Henri Idrovo Updated on ・3 min read

originally posted on my blog at henricodesjava.blog

Hello world! I'm currently reading Head First Design Patterns: A Brain-Friendly Guide, and if it is your first time reading about design patterns in Object Oriented Programming(OOP), its a great start! I wouldn't recommend it as a reference guide, because there are a ton of examples, illustrations, and informal descriptions. So here is the first pattern introduced in the book.

Strategy PatternDefines a family of algorithms, encapsulates each one, and makes them interchangeable. The strategy lets the algorithm vary independently from clients that use it.

Sounds confusing, but it is actually pretty simple. The pattern is based on the following three principles:

  1. Identify the aspect of your application that vary and separate them from what stays the same.
  2. Program to an interface, not an implementation.
  3. Favor composition over inheritance.

Let me try to clear up what these principles mean. I'll use an example that is different from the one included in the book.

Lets say we are starting a robot company. Like Boston Dynamics. We want to build all types of robots. Check out the class below that will be used for all our robot's behaviors. Screen Shot 2017-09-13 at 9.09.24 PM.png

Now here is where we apply our first principle. Our imaginary company needs to be be able to build robots that operate on land, air, or water. All our robots also need to be able to give the greeting, "Hello world!". The greeting is the behavior that stays the same. The other three behaviors are what will change from robot to robot. So we will separate the 'Walk', 'Swim', and 'Fly' behavior from the 'Greeting' behavior. Lets see how.

The second principle states it is better to use interfaces rather than direct implementations. So what we will do is create interfaces for each behavior group that has the possibility of changing. This way there can exist many different implementations of each, see below.

Screen Shot 2017-09-13 at 11.43.18 PM.png

When it comes time to create a specific implementation of a robot, we will extend the Robot class, and in this way have access to the 'greeting' behavior. The greeting behavior can be coded in the Robot class since this will be the same for all robots we ever create. Then when it comes time to add a Walk, Swim, or Fly behavior to our new robot, it will not inherit this behavior from the original Robot class, but it will instead have an implementation of an interface assigned to it, in other words, it will be composed during runtime. This successfully separates these changing, and non-changing behaviors using interfaces. This way we follow our third design principle. Take a look at the diagram below for an overhead view of it all, including three example robots, Dog, Shark, and Eagle robots.

Screen Shot 2017-09-14 at 10.40.28 AM.png


So thats it! That is the quick introduction to the Strategy Pattern. Above you can see what a complete class diagram would look like when we implement the Strategy Pattern. Thanks for reading 👋🏽

(originally posted at my personal blog: https://henricodesjava.blog)


Editor guide
jvanbruegge profile image
Jan van Brügge

Always when I see Java code and "best practices", I always wonder how people can still use such a verbose and limited language (and paradigm). Let's express your example in Haskell:

{-# LANGUAGE ConstraintKind #-}

class CanSwim a where
    doSwim :: a -> IO()

class CanGreet a where
    doGreet :: a -> IO()

instance CanSwim DogRobot where
    doSwim = dogSwim

instance CanSwim SharkRobot where
    doSwim = sharkSwim

-- ...

type Robot = (CanSwim a, CanGreet a, CanFly a, CanWalk a)

No need for complex class hierarchies, you simply have a few functions following an interface (type class). A robot then is just the composition of the type classes.

marlysson profile image
Marlysson Silva

Object oriented programming is a limited paradigm to express certain behaviors?

jvanbruegge profile image
Jan van Brügge

No, Java is limited as a language. OO is verbose and leads to unnecessary abstractions (read: convoluted class hierachies).
E.g. your example:
In haskell: A bunch of functions that follow an interface (1 level)
OO: Robot class, subclass, Behavior interface, behavior implementation (4 levels)