Стратегія (англ. Strategy) — поведінковий шаблон проєктування, призначений для визначення сімейства алгоритмів,
інкапсуляції кожного з них та забезпечення їх взаємозамінності. Це дозволяє вибирати алгоритм шляхом визначення
відповідного класу. Шаблон Strategy дозволяє змінювати обраний алгоритм незалежно від об’єктів-клієнтів,
які його використовують.
-
Strategies
-
AddStrategy.php
<?php namespace DesignPatterns\Behavioral\Strategy\Strategies; /** * Class AddStrategy * @package DesignPatterns\Behavioral\Strategy\Strategies */ class AddStrategy implements StrategyInterface { /** * @param int $x * @param int $y * * @return int */ public function algorithm(int $x, int $y): int { return $x + $y; } }
-
MultiplyStrategy.php
<?php namespace DesignPatterns\Behavioral\Strategy\Strategies; /** * Class MultiplyStrategy * @package DesignPatterns\Behavioral\Strategy\Strategies */ class MultiplyStrategy implements StrategyInterface { /** * @param int $x * @param int $y * * @return int */ public function algorithm(int $x, int $y): int { return $x * $y; } }
-
StrategyInterface.php
<?php namespace DesignPatterns\Behavioral\Strategy\Strategies; /** * Interface StrategyInterface * @package DesignPatterns\Behavioral\Strategy\Strategies */ interface StrategyInterface { /** * @param int $x * @param int $y * * @return int */ public function algorithm(int $x, int $y): int; }
-
SubtractStrategy.php
<?php namespace DesignPatterns\Behavioral\Strategy\Strategies; /** * Class SubtractStrategy * @package DesignPatterns\Behavioral\Strategy\Strategies */ class SubtractStrategy implements StrategyInterface { /** * @param int $x * @param int $y * * @return int */ public function algorithm(int $x, int $y): int { return $x - $y; } }
-
-
SimpleCalculator.php
<?php namespace DesignPatterns\Behavioral\Strategy; use DesignPatterns\Behavioral\Strategy\Strategies\StrategyInterface; /** * Class SimpleCalculator * @package DesignPatterns\Behavioral\Strategy */ class SimpleCalculator { /** * @var int */ private $x; /** * @var int */ private $y; /** * @var StrategyInterface */ private $strategy; /** * SimpleCalculator constructor. * * @param int $x * @param int $y */ public function __construct(int $x, int $y) { $this->x = $x; $this->y = $y; } /** * @param StrategyInterface $strategy * * @return void */ public function setStrategy(StrategyInterface $strategy) { $this->strategy = $strategy; } /** * @return int */ public function execute(): int { return $this->strategy->algorithm($this->x, $this->y); } }
Test case:
StrategyTest.php
<?php
namespace DesignPatterns\Tests\Behavioral\Strategy;
use DesignPatterns\Behavioral\Strategy\SimpleCalculator;
use DesignPatterns\Behavioral\Strategy\Strategies\AddStrategy;
use DesignPatterns\Behavioral\Strategy\Strategies\MultiplyStrategy;
use DesignPatterns\Behavioral\Strategy\Strategies\SubtractStrategy;
use PHPUnit_Framework_TestCase;
class StrategyTest extends PHPUnit_Framework_TestCase
{
public function provideIntegersForAdd()
{
return [
[2, 3, 5],
[8, 3, 11],
[-3, 5, 2],
[23, -3, 20],
[-42, -20, -62],
];
}
public function provideIntegersForSub()
{
return [
[2, 3, -1],
[8, 3, 5],
[-3, 5, -8],
[23, -3, 26],
[-42, -20, -22],
];
}
public function provideIntegersForMulti()
{
return [
[2, 3, 6],
[8, 3, 24],
[-3, 5, -15],
[23, -3, -69],
[-42, -20, 840],
];
}
/**
* @dataProvider provideIntegersForAdd
*
* @param int $x
* @param int $y
* @param int $expected
*/
public function testSimpleCalculatorWithAddStrategy(int $x, int $y, int $expected)
{
$simpleCalculator = new SimpleCalculator($x, $y);
$simpleCalculator->setStrategy(new AddStrategy());
$this->assertEquals($expected, $simpleCalculator->execute());
}
/**
* @dataProvider provideIntegersForSub
*
* @param int $x
* @param int $y
* @param int $expected
*/
public function testSimpleCalculatorWithSubtractStrategy(int $x, int $y, int $expected)
{
$simpleCalculator = new SimpleCalculator($x, $y);
$simpleCalculator->setStrategy(new SubtractStrategy());
$this->assertEquals($expected, $simpleCalculator->execute());
}
/**
* @dataProvider provideIntegersForMulti
*
* @param int $x
* @param int $y
* @param int $expected
*/
public function testSimpleCalculatorWithMultiplyStrategy(int $x, int $y, int $expected)
{
$simpleCalculator = new SimpleCalculator($x, $y);
$simpleCalculator->setStrategy(new MultiplyStrategy());
$this->assertEquals($expected, $simpleCalculator->execute());
}
}