Strategy design pattern presentation

tl;dr: Program to an interface, not an implementation

Wait, strategy?
WTF is that?

 

 

a careful plan or method for achieving a particular goal.

 

 

 

 

 

 

 

 

No battle plan ever survived first contact with the enemy. (Murphy's  law of combat, or more accurately Von Moltke, a Prussian general during Bismark era)

Real life example

The Strategy pattern allows you to have multiple strategies to solve one problem.

Its motto is the following:

Program to an interface, not an implementation

Ok, Ok... real real life example.

Existing class

class PresentationBuilder
{
  public function createPresentation($keywords)
  {
    $imageSearch = new SearchImageTool();
    $this->images = $imageSearch->find($keywords);
    // ...
  }
}

Quick fix

class PresentationBuilder
{
  public function createPresentation($keywords, $isWd)
  {
    if ($isWd) {
      $imageSearch = new ImprovedImageSearch();
    } else {
      $imageSearch = new NormalImageSearch();
    }
    $this->images = $imageSearch->find($keywords);
    // ...
  }
}
class PresentationBuilder {
  protected $imageSearcher;
  public function __construct(ImageSearchInterface $imageSearcher) { 
     $this->imageSearcher = $imageSearcher;
  }

  public function createPresentation($keywords) {
    $images = $this->imageSearch->find($keywords);
    // ...
  }
}

interface ImageSearchInterface {
  public function findByKeywords($keywords);
}
class ImprovedImageSearch implements ImageSearchInterface {
  public function findByKeywords($keywords) {
    // Go get images from BonjourMadame.
  }  
}
class NormalImageSearch implements ImageSearchInterface {
  public function findByKeywords($keywords) {
    // Go get images from Google
  }  
}

The images are good, but the code is bad...

Beware the Pattern!

// Presentation for WD Strategy Pattern
$presentationBuilder = new PresentationBuilder(new ImprovedImageSearch());
$presentation = $presentationBuilder->createPresentation('Strategy pattern');

Now I just have to decide in my own project which strategy to use.

And, if someone more into bananas are not happy with the 2 provided strategies, they can build their own easily:

class BananaImageSearch implements ImageSearchInterface {
  public function findByKeywords($keywords) {
    // Go get images from some banana picture bank.
  }  
}

$presentationBuilder = new PresentationBuilder(new BananaImageSearch());
$presentation = new $presentationBuilder->createPresentation('Banana split');

Pros

  • Integrates nicely with dependency injections
  • Allow flexibility for reusers of your package
  • Avoid an ugly switch/case
  • Strategies are reusable in other contextes

Cons

  • Users must be aware of the different strategies
  • Add a new dependency
  • All strategies must implement the same interface; that's sometime hard to achieve
Made with Slides.com