Design Patterns in PHP - Strategy Pattern

Last week's post about the Factory Method Pattern in PHP seemed to go down quite well so I thought I'd get onto another one fairly sharpish.
By Sam Holman
30th November 2010
So today i'll be talking about the Strategy Pattern, which to my mind, is one of the patterns that demonstrates beautiful encapsulation in OOP (Object Orientated Programming).

The Strategy Pattern is used to decouple an algorithm from the context in which it is used. I'm going to equate this example to a real world scenario starring a man, I’ll call him Bob.
Bob needs to get to work in a morning. Now it's up to him how he goes about getting there. From the point of view of an outsider - Bob’s boss for instance, it doesn’t really matter how he gets to work, just that he arrives on time.
When Bob starts his day he can choose the method by which he gets to work, based on what is available. He can assess if he has a car, if it is in a serviceable state and if the roads are clear. If not, Bob may decide to take the train and take into account his proximity from the station and the availability of a given train. But no matter what Bob's selected strategy may be, he is simply performing the action of getting to work.
Below is an example in PHP demonstrating this pattern for Bob getting to work:
ITransportStrategy.inc.php
Car.inc.php
Train.inc.php
Commuter.inc.php
isAvailable())
            {
                $this->_strategy = $method;
                break;
            }
        }

        if (!isset($this->_strategy)) {
            throw new Exception('No transport methods available');
        }
    }

    public function travel(Location $location)
    {
        if ($this->_strategy) {
            return $this->_strategy->travel($location);
        }

        return false;
    } 
}
bob.php
travel(Map::getLocation('work'))) {
    // Bob got to work, nobody cares how :-)    
}
As you can see, Bob is created as an instance of the Commuter class which stores a copy of it's $_strategy object. This object is then used when our Commuter wants to travel anywhere. You can assume that the Location and Map classes are implemented elsewhere as their implementation is not strictly relevant to this actual example.
One point to note from the code above is the $_strategies array inside the Commuter class represents a preference order of all possible strategies, and the commuter will use the first one that is available. Also, the method for selecting which strategy to use is not defined as part of this design pattern, and it would have been equally as valid to pass the strategy to the class on construction, however if the strategy was provided to the travel method then this would actually be more akin to the Visitor pattern.

Possible uses

So, the Strategy Pattern can be used when you have to perform an action but don't care about how that action is actually performed. We've found this pattern useful, for example, in a caching class and implemented different strategies for Memcached, APC, or a DB cache and the system would then use whichever was available.
I hope you have found this article informative, and keep an eye out for the next one!
Comments welcome on twitter, @labelmedia :-)

Like this? Sign up to our newsletter for more!

Comments

Vanessa 8th August 2012
I found this article very instructive. It was hard for me to understand the strategy pattern but you did it in the best and clear way. Thanks for posting. Continue on doing so ;)
Adriano 13th August 2012
Very nice article thanks for work
Luke 27th October 2012
An informative and easy to understand article.
John 11th November 2012
Thanks for the article. It made it very easy for me to understand the strategy pattern.
yoko 26th April 2013
Doesn't look like a Strategy at all, what you demonstrate is an ordinary subclassing
Code Monkey 3rd July 2013
Bit of a howler in the first paragraph Sam surely?
Object 'Orientated' Programming?
Should it not be Object 'Oriented' Programming?
Sam Holman 4th July 2013
@Code Monkey: I think that's actually more of a British vs American English difference when you look at the etymology of the words. :-)

Add your own comment

© 2014 Label Media
We are recruiting