User Tools

Site Tools


php:strategy

STRATEGY (POLICY) PATTERN

02.04.2010

The Strategy Pattern is useful for situations where it is necessary to dynamically swap the algorithms used in an application. The strategy pattern is intended to provide a means to define a family of algorithms, encapsulate each one as an object, and make them interchangeable. The strategy pattern lets the algorithms vary independently from clients that use them.

Participants

  • Context: uses a Strategy object, outsourcing part of its behavior.
  • Strategy: contract that Context sees.
  • ConcreteStrategy: implementation of Strategy as a particular behavior.

Switch statements or if-else chains are candidates for refactoring to a Strategy pattern (as they are for the State pattern). The difference between the two is their intent: State encapsulates data and possibly the transition to other States; a Strategy object usually does not produce other Strategy implementations and hides complex behavior.

In our example we implement a very simple (and unsafe!) Text Formatting class. Instead to code the formatting styles inside the class, we build 3 classes (ContextStrategy) based on the ShowText interface (Strategy).

Out Context class looks like:

class TextFormat {
    private $strategy = NULL;
 
    public function __construct($initial_strategy = null) {
        if ($initial_strategy) $this->strategy = $initial_strategy;
        if (!$this->strategy) $this->strategy = new BoldShowText(); // default strategy
    }
 
    public function changeFormat($new_strategy) {
        $this->strategy = $new_strategy;
    }
 
    public function formatText($text) {
        $this->strategy->display($text);
        echo "<br/>";
    }
}

We can initialize the class with a strategy, or use it as it is (and in this case, the new BoldShowText strategy will be setup as default). Or we can even change the strategies on the fly using changeFormat method.

The Strategies implemenations look like:

interface ShowText { public function display($text); }
 
class BoldShowText implements ShowText {
    public function display($text) {
        echo "<b>$text</b>";
    }
}
 
class ItalicShowText implements ShowText {
    public function display($text) {
        echo "<i>$text</i>";
    }
}
 
class CapsShowText implements ShowText {
    public function display($text) {
        echo strtoupper($text);
    }
}

And you can use it this way:

<?php
$formatObj = new TextFormat();
$formatObj->formatText("This will be bold text - the default strategy here!");
 
$formatObj = new TextFormat(new CapsShowText);
$formatObj->formatText("This will be UPPERCASE text - setting the strategy in the constructor!");
 
$formatObj = new TextFormat();
$formatObj->changeFormat(new ItalicShowText);
$formatObj->formatText("This will be Italic text - strategy set up by changeFormat method!");
?>

Put that in a file on your webserver and you'll see different displaying style for the text.

References:

Five Common PHP Patterns
Giorgio Sironi example (credit for image and some text)
Wikipedia

php/strategy.txt · Last modified: 2013/03/16 17:40 (external edit)