Strategy design pattern

The Strategy design pattern exists to allow us to alter the behavior of an object at runtime.

Let's suppose we have a class that will raise a number to a power, but at runtime we want to alter whether we square or cube a number.

Let's start off by defining an interface a function that will raise a number to a given power:

<?php 
 
interface Power 
{ 
  public function raise(int $number): int; 
} 

We can accordingly define classes to Square and also Cube a given number by implementing the interface.

Here's our Square class:

<?php 
 
class Square implements Power 
{ 
  public function raise(int $number): int 
  { 
    return pow($number, 2); 
  } 
} 

And let's define our Cube class:

<?php 
 
class Cube implements Power 
{ 
  public function raise(int $number): int 
  { 
    return pow($number, 3); 
  } 
} 

We can now build a class that will essentially use one of these classes to process a number.

Here's the class:

<?php 
 
class RaiseNumber 
{ 
  public function __construct(Power $strategy) 
  { 
    $this->strategy = $strategy; 
  } 
 
  public function raise(int $number) 
  { 
    return $this->strategy->raise($number); 
  } 
} 

Now we can demonstrate this whole setup using an index.php file:

<?php 
 
require_once('Power.php'); 
require_once('Square.php'); 
require_once('Cube.php'); 
require_once('RaiseNumber.php'); 
 
 
$processor = new RaiseNumber(new Square()); 
 
var_dump($processor->raise(5)); 

The output is as expected, 52 is 25.

Here's the output:

Strategy design pattern

We can swap the Square object with the Cube object in our index.php file:

<?php 
 
require_once('Power.php'); 
require_once('Square.php'); 
require_once('Cube.php'); 
require_once('RaiseNumber.php'); 
 
 
$processor = new RaiseNumber(new Cube()); 
 
var_dump($processor->raise(5)); 

Here's the output of the updated script:

Strategy design pattern

So far so good; but the reason that this is great is the fact that we can dynamically add logic that actually changes the operation of the class.

Here's a rather crude demonstration of all this:

<?php 
 
require_once('Power.php'); 
require_once('Square.php'); 
require_once('Cube.php'); 
require_once('RaiseNumber.php'); 
 
if (isset($_GET['n'])) { 
  $number = $_GET['n']; 
} else { 
  $number = 0; 
} 
 
if ($number < 5) { 
  $power = new Cube(); 
} else { 
  $power = new Square(); 
} 
 
$processor = new RaiseNumber($power); 
 
var_dump($processor->raise($number)); 

So just to demonstrate this, let's run the script with the nGET variable set to 4, which should cube the number 4, giving an output of 64:

Strategy design pattern

Now if we pass through the number 6, we expect the script to square the number 6, giving an output of 36:

Strategy design pattern

In this design pattern, we have done a lot:

  • We defined a family of algorithms, bound by one common interface
  • These algorithms are interchangeable; they can be swapped in and out without affecting the client implementation
  • We encapsulated each algorithm within a class

Now we can vary the algorithm independently from the clients that use it.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.224.44.53