3.10. State
3.10.1. Zweck
Kapselt verschiedene Verhaltensweisen für die selbe Routine basierend auf einem Objekt-State. Das kann ein sauberer Weg für ein Objekt sein, sein Verhalten während der Laufzeit ohne komplexe konditionale Bedingungen ändern zu können.
3.10.2. UML-Diagramm
3.10.3. Code
Du findest den Code hierzu auf GitHub
ContextOrder.php
1<?php
2
3declare(strict_types=1);
4
5namespace DesignPatterns\Behavioral\State;
6
7class ContextOrder
8{
9 private StateOrder $state;
10
11 public static function create(): ContextOrder
12 {
13 $order = new self();
14 $order->state = new CreateOrder();
15
16 return $order;
17 }
18
19 public function setState(StateOrder $state): void
20 {
21 $this->state = $state;
22 }
23
24 public function proceedToNext(): void
25 {
26 $this->state->proceedToNext($this);
27 }
28
29 public function toString(): string
30 {
31 return $this->state->toString();
32 }
33}
StateOrder.php
1<?php
2
3declare(strict_types=1);
4
5namespace DesignPatterns\Behavioral\State;
6
7interface StateOrder
8{
9 public function proceedToNext(ContextOrder $context): void;
10
11 public function toString(): string;
12}
CreateOrder.php
1<?php
2
3declare(strict_types=1);
4
5namespace DesignPatterns\Behavioral\State;
6
7class CreateOrder implements StateOrder
8{
9 public function proceedToNext(ContextOrder $context): void
10 {
11 $context->setState(new ShippingOrder());
12 }
13
14 public function toString(): string
15 {
16 return 'created';
17 }
18}
ShippingOrder.php
1<?php
2
3declare(strict_types=1);
4
5namespace DesignPatterns\Behavioral\State;
6
7class ShippingOrder implements StateOrder
8{
9 public function proceedToNext(ContextOrder $context): void
10 {
11 $context->setState(new OrderDone());
12 }
13
14 public function toString(): string
15 {
16 return 'shipped';
17 }
18}
OrderDone.php
1<?php
2
3declare(strict_types=1);
4
5namespace DesignPatterns\Behavioral\State;
6
7class OrderDone implements StateOrder
8{
9 public function proceedToNext(ContextOrder $context): void
10 {
11 // there is nothing more to do
12 }
13
14 public function toString(): string
15 {
16 return 'done';
17 }
18}
3.10.4. Test
Tests/StateTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace DesignPatterns\Behavioral\State\Tests;
6
7use DesignPatterns\Behavioral\State\ContextOrder;
8use PHPUnit\Framework\TestCase;
9
10class StateTest extends TestCase
11{
12 public function testIsCreatedWithStateCreated(): void
13 {
14 $orderContext = ContextOrder::create();
15
16 $this->assertSame('created', $orderContext->toString());
17 }
18
19 public function testCanProceedToStateShipped(): void
20 {
21 $contextOrder = ContextOrder::create();
22 $contextOrder->proceedToNext();
23
24 $this->assertSame('shipped', $contextOrder->toString());
25 }
26
27 public function testCanProceedToStateDone(): void
28 {
29 $contextOrder = ContextOrder::create();
30 $contextOrder->proceedToNext();
31 $contextOrder->proceedToNext();
32
33 $this->assertSame('done', $contextOrder->toString());
34 }
35
36 public function testStateDoneIsTheLastPossibleState(): void
37 {
38 $contextOrder = ContextOrder::create();
39 $contextOrder->proceedToNext();
40 $contextOrder->proceedToNext();
41 $contextOrder->proceedToNext();
42
43 $this->assertSame('done', $contextOrder->toString());
44 }
45}