3.10. State
3.10.1. Doel
Kapselt wisselend gedrag in voor dezelfde routine op basis van de toestand van een object. Dit kan een schonere manier zijn voor een object om zijn gedrag tijdens runtime te veranderen zonder zijn toevlucht te nemen tot grote monolithische voorwaardelijke uitspraken.
3.10.2. UML Diagram
3.10.3. Code
Je kan deze broncode terugvinden op 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}