objectif
Séparez les «stratégies» et permettez-leur de passer rapidement les unes aux autres. De plus, ce modèle est une bonne alternative à l'héritage (alternative à l'utilisation de classes abstraites étendues).
exemple
-
Version simplifiée des tests unitaires: par exemple, basculer entre l'utilisation du stockage de fichiers et du stockage en mémoire
-
Trier une liste d'objets, un par date et un par identifiant
Graphiques UML
Code
- Context.php
<?php
namespace DesignPatterns\Behavioral\Strategy;
class Context
{
/**
* @var ComparatorInterface
*/
private $comparator;
public function __construct(ComparatorInterface $comparator)
{
$this->comparator = $comparator;
}
public function executeStrategy(array $elements) : array
{
uasort($elements, [$this->comparator, 'compare']);
return $elements;
}
}
- ComparatorInterface.php
<?php
namespace DesignPatterns\Behavioral\Strategy;
interface ComparatorInterface
{
/**
* @param mixed $a
* @param mixed $b
*
* @return int
*/
public function compare($a, $b): int;
}
- DateComparator.php
<?php
namespace DesignPatterns\Behavioral\Strategy;
class DateComparator implements ComparatorInterface
{
/**
* @param mixed $a
* @param mixed $b
*
* @return int
*/
public function compare($a, $b): int
{
$aDate = new \DateTime($a['date']);
$bDate = new \DateTime($b['date']);
return $aDate <=> $bDate;
}
}
- IdComparator.php
<?php
namespace DesignPatterns\Behavioral\Strategy;
class IdComparator implements ComparatorInterface
{
/**
* @param mixed $a
* @param mixed $b
*
* @return int
*/
public function compare($a, $b): int
{
return $a['id'] <=> $b['id'];
}
}
tester
- Tests / StrategyTest.php
<?php
namespace DesignPatterns\Behavioral\Strategy\Tests;
use DesignPatterns\Behavioral\Strategy\Context;
use DesignPatterns\Behavioral\Strategy\DateComparator;
use DesignPatterns\Behavioral\Strategy\IdComparator;
use PHPUnit\Framework\TestCase;
class StrategyTest extends TestCase
{
public function provideIntegers()
{
return [
[
[['id' => 2], ['id' => 1], ['id' => 3]],
['id' => 1],
],
[
[['id' => 3], ['id' => 2], ['id' => 1]],
['id' => 1],
],
];
}
public function provideDates()
{
return [
[
[['date' => '2014-03-03'], ['date' => '2015-03-02'], ['date' => '2013-03-01']],
['date' => '2013-03-01'],
],
[
[['date' => '2014-02-03'], ['date' => '2013-02-01'], ['date' => '2015-02-02']],
['date' => '2013-02-01'],
],
];
}
/**
* @dataProvider provideIntegers
*
* @param array $collection
* @param array $expected
*/
public function testIdComparator($collection, $expected)
{
$obj = new Context(new IdComparator());
$elements = $obj->executeStrategy($collection);
$firstElement = array_shift($elements);
$this->assertEquals($expected, $firstElement);
}
/**
* @dataProvider provideDates
*
* @param array $collection
* @param array $expected
*/
public function testDateComparator($collection, $expected)
{
$obj = new Context(new DateComparator());
$elements = $obj->executeStrategy($collection);
$firstElement = array_shift($elements);
$this->assertEquals($expected, $firstElement);
}
}
Le chemin de croissance de PHP Internet Architect * Le guide ultime des «modèles de conception»
Entretien avec 10 entreprises, obtenez 9 offres, questions d'entretien PHP en 2020
★ Si vous aimez mon article et que vous souhaitez communiquer et apprendre avec des développeurs plus expérimentés, obtenir plus de conseils techniques et des conseils liés aux entretiens avec de grandes entreprises, bienvenue à rejoindre notre groupe, mot de passe: phpzh
Le dernier tutoriel avancé PHP en 2020, série complète!
Si le contenu est bon, j'espère que tout le monde vous soutiendra et vous encouragera à donner un `` like / like '' et à communiquer ensemble; de plus, si vous avez des questions, vous pouvez suggérer ce que vous voulez voir dans les commentaires.