3.11. Strategy
3.11.1. Terminologie:
Context
Strategy
Concrete Strategy
3.11.2. Zweck
Mehrere Strategien zu trennen und schnelles Hin- und Herrschaften zwischen diesen zu ermöglichen. Außerdem ist dieses Muster eine perfekte Alternative zu Vererbung von einer abstrakten Klasse.
3.11.3. Beispiele
eine Liste an Objekten zu sortieren, wobei jede Strategie dies anhand anderer Daten vornimmt (Datum, ID, etc.)
Unit-Tests zu vereinfachen indem zwischen darunterliegendem Storage umgeschalten wird: Datei vs. in-Memory
3.11.4. UML-Diagramm

3.11.5. Code
Du findest den Code hierzu auf GitHub
Context.php
1<?php
2
3declare(strict_types=1);
4
5namespace DesignPatterns\Behavioral\Strategy;
6
7class Context
8{
9 public function __construct(private Comparator $comparator)
10 {
11 }
12
13 public function executeStrategy(array $elements): array
14 {
15 uasort($elements, [$this->comparator, 'compare']);
16
17 return $elements;
18 }
19}
Comparator.php
1<?php
2
3declare(strict_types=1);
4
5namespace DesignPatterns\Behavioral\Strategy;
6
7interface Comparator
8{
9 /**
10 * @param mixed $a
11 * @param mixed $b
12 */
13 public function compare($a, $b): int;
14}
DateComparator.php
1<?php
2
3declare(strict_types=1);
4
5namespace DesignPatterns\Behavioral\Strategy;
6
7use DateTime;
8
9class DateComparator implements Comparator
10{
11 public function compare($a, $b): int
12 {
13 $aDate = new DateTime($a['date']);
14 $bDate = new DateTime($b['date']);
15
16 return $aDate <=> $bDate;
17 }
18}
IdComparator.php
1<?php
2
3declare(strict_types=1);
4
5namespace DesignPatterns\Behavioral\Strategy;
6
7class IdComparator implements Comparator
8{
9 public function compare($a, $b): int
10 {
11 return $a['id'] <=> $b['id'];
12 }
13}
3.11.6. Test
Tests/StrategyTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace DesignPatterns\Behavioral\Strategy\Tests;
6
7use DesignPatterns\Behavioral\Strategy\Context;
8use DesignPatterns\Behavioral\Strategy\DateComparator;
9use DesignPatterns\Behavioral\Strategy\IdComparator;
10use PHPUnit\Framework\TestCase;
11
12class StrategyTest extends TestCase
13{
14 public function provideIntegers()
15 {
16 return [
17 [
18 [['id' => 2], ['id' => 1], ['id' => 3]],
19 ['id' => 1],
20 ],
21 [
22 [['id' => 3], ['id' => 2], ['id' => 1]],
23 ['id' => 1],
24 ],
25 ];
26 }
27
28 public function provideDates()
29 {
30 return [
31 [
32 [['date' => '2014-03-03'], ['date' => '2015-03-02'], ['date' => '2013-03-01']],
33 ['date' => '2013-03-01'],
34 ],
35 [
36 [['date' => '2014-02-03'], ['date' => '2013-02-01'], ['date' => '2015-02-02']],
37 ['date' => '2013-02-01'],
38 ],
39 ];
40 }
41
42 /**
43 * @dataProvider provideIntegers
44 *
45 * @param array $collection
46 * @param array $expected
47 */
48 public function testIdComparator($collection, $expected)
49 {
50 $obj = new Context(new IdComparator());
51 $elements = $obj->executeStrategy($collection);
52
53 $firstElement = array_shift($elements);
54 $this->assertSame($expected, $firstElement);
55 }
56
57 /**
58 * @dataProvider provideDates
59 *
60 * @param array $collection
61 * @param array $expected
62 */
63 public function testDateComparator($collection, $expected)
64 {
65 $obj = new Context(new DateComparator());
66 $elements = $obj->executeStrategy($collection);
67
68 $firstElement = array_shift($elements);
69 $this->assertSame($expected, $firstElement);
70 }
71}