diff --git a/Behavioral/State/ContextOrder.php b/Behavioral/State/ContextOrder.php new file mode 100644 index 0000000..b05537d --- /dev/null +++ b/Behavioral/State/ContextOrder.php @@ -0,0 +1,26 @@ +done(); + } + + public function getStatus(): string + { + return static::$state->getStatus(); + } +} diff --git a/Behavioral/State/CreateOrder.php b/Behavioral/State/CreateOrder.php index 4a35ac3..9c95b61 100644 --- a/Behavioral/State/CreateOrder.php +++ b/Behavioral/State/CreateOrder.php @@ -2,34 +2,15 @@ namespace DesignPatterns\Behavioral\State; -class CreateOrder implements Order +class CreateOrder extends StateOrder { - /** - * @var array - */ - private $details; - - /** - * @param array $details - */ - public function __construct(array $details) + public function __construct() { - $this->details = $details; + $this->setStatus('created'); } - public function shipOrder() + protected function done() { - $this->details['status'] = 'shipping'; - $this->details['updatedTime'] = time(); - } - - public function completeOrder() - { - throw new \Exception('Can not complete the order which status is created'); - } - - public function getStatus(): string - { - return $this->details['status']; + static::$state = new ShippingOrder(); } } diff --git a/Behavioral/State/Order.php b/Behavioral/State/Order.php deleted file mode 100644 index ea85159..0000000 --- a/Behavioral/State/Order.php +++ /dev/null @@ -1,18 +0,0 @@ - ['status' => 'created'], - 2 => ['status' => 'shipping'], - 3 => ['status' => 'completed'], - ]; - - public static function findById(int $id): Order - { - if (!isset(self::$orders[$id])) { - throw new \InvalidArgumentException(sprintf('Order with id %d does not exist', $id)); - } - - $order = self::$orders[$id]; - - switch ($order['status']) { - case 'created': - return new CreateOrder($order); - case 'shipping': - return new ShippingOrder($order); - default: - throw new \InvalidArgumentException('Invalid order status given'); - break; - } - } -} diff --git a/Behavioral/State/README.rst b/Behavioral/State/README.rst index 30b3e1a..50e3cbd 100644 --- a/Behavioral/State/README.rst +++ b/Behavioral/State/README.rst @@ -20,15 +20,15 @@ Code You can also find this code on `GitHub`_ -OrderRepository.php +ContextOrder.php -.. literalinclude:: OrderRepository.php +.. literalinclude:: ContextOrder.php :language: php :linenos: -Order.php +StateOrder.php -.. literalinclude:: Order.php +.. literalinclude:: StateOrder.php :language: php :linenos: diff --git a/Behavioral/State/ShippingOrder.php b/Behavioral/State/ShippingOrder.php index 41198b2..06032eb 100644 --- a/Behavioral/State/ShippingOrder.php +++ b/Behavioral/State/ShippingOrder.php @@ -2,34 +2,15 @@ namespace DesignPatterns\Behavioral\State; -class ShippingOrder implements Order +class ShippingOrder extends StateOrder { - /** - * @var array - */ - private $details; - - /** - * @param array $details - */ - public function __construct(array $details) + public function __construct() { - $this->details = $details; + $this->setStatus('shipping'); } - public function shipOrder() + protected function done() { - throw new \Exception('Can not ship the order which status is shipping!'); - } - - public function completeOrder() - { - $this->details['status'] = 'completed'; - $this->details['updatedTime'] = time(); - } - - public function getStatus(): string - { - return $this->details['status']; + $this->setStatus('completed'); } } diff --git a/Behavioral/State/StateOrder.php b/Behavioral/State/StateOrder.php new file mode 100644 index 0000000..b003cb7 --- /dev/null +++ b/Behavioral/State/StateOrder.php @@ -0,0 +1,32 @@ +details['status'] = $status; + $this->details['updatedTime'] = time(); + } + + protected function getStatus(): string + { + return $this->details['status']; + } +} diff --git a/Behavioral/State/Tests/StateTest.php b/Behavioral/State/Tests/StateTest.php index 7f9ea4e..834c02c 100644 --- a/Behavioral/State/Tests/StateTest.php +++ b/Behavioral/State/Tests/StateTest.php @@ -2,33 +2,30 @@ namespace DesignPatterns\Behavioral\State\Tests; -use DesignPatterns\Behavioral\State\OrderRepository; +use DesignPatterns\Behavioral\State\ContextOrder; +use DesignPatterns\Behavioral\State\CreateOrder; use PHPUnit\Framework\TestCase; class StateTest extends TestCase { public function testCanShipCreatedOrder() { - $order = (new OrderRepository())->findById(1); - $order->shipOrder(); + $order = new CreateOrder(); + $contextOrder = new ContextOrder(); + $contextOrder->setState($order); + $contextOrder->done(); - $this->assertEquals('shipping', $order->getStatus()); + $this->assertEquals('shipping', $contextOrder->getStatus()); } public function testCanCompleteShippedOrder() { - $order = (new OrderRepository())->findById(2); - $order->completeOrder(); + $order = new CreateOrder(); + $contextOrder = new ContextOrder(); + $contextOrder->setState($order); + $contextOrder->done(); + $contextOrder->done(); - $this->assertEquals('completed', $order->getStatus()); - } - - /** - * @expectedException \Exception - */ - public function testThrowsExceptionWhenTryingToCompleteCreatedOrder() - { - $order = (new OrderRepository())->findById(1); - $order->completeOrder(); + $this->assertEquals('completed', $contextOrder->getStatus()); } } diff --git a/Behavioral/State/uml/uml.png b/Behavioral/State/uml/uml.png index 847a4e4..e95b39a 100644 Binary files a/Behavioral/State/uml/uml.png and b/Behavioral/State/uml/uml.png differ diff --git a/Behavioral/State/uml/uml.svg b/Behavioral/State/uml/uml.svg index 2b97e07..7cffe9c 100644 --- a/Behavioral/State/uml/uml.svg +++ b/Behavioral/State/uml/uml.svg @@ -1,460 +1,665 @@ - + - + - + - + - + - + + + + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - + - - + + - + - - + + - - + + - - + + - - + + - - - - - - order + + + + + + __construct() - - + + - - + + - - - - - __construct(order) + + + + + + done() - - + + - - + + + - - - - - shipOrder() + + - - + + ShippingOrder - - - - - completeOrder() + + ShippingOrder - - + + - - - + + - - + + - - CreateOrder + + + + + + __construct() - - CreateOrder + + - - + + - - + + + + + + done() - - + + - - + + + - - - - - __construct() + + - - + + ShippingOrder - - + + ShippingOrder - - - - - getOrder(id) + + - - + + - - - + + - - + + - - OrderFactory + + + + + + __construct() - - OrderFactory + + - - + + - - + + + + + + done() - - + + - - + + + - - - - - shipAction(id) + + - - + + CreateOrder - - - - - completeAction(id) + + CreateOrder - - + + - - - + + - - + + - - OrderController + + + + + + __construct() - - OrderController + + - - + + - - + + + + + + done() - - + + - - + + + - - - - - shipOrder() + + - - + + CreateOrder - - - - - completeOrder() + + CreateOrder - - + + - - - + + - - + + - - OrderInterface + + - - OrderInterface + + + + + + details - - + + - - + + + + + + + state + + + + + + + + + + + + + done() + + + - - + + + + + + setStatus(status) + + + + + + + + + + getStatus() + + + + + + + - - + + + + + StateOrder + + + StateOrder + + + + + + + + + + + + + + + + details + + + + + + + + + + + state + + + + + + + + + + + + + done() + + + + + + + + + + setStatus(status) - - - - - - order + + + + + + + + + getStatus() + + + + + + + + + + + + + StateOrder + + + StateOrder + + + + + + + + + + + + + + + + + + + getState() + + + + + + + + + + setState(state) + + + + + + + + + + done() + + + + + + + + + + getStatus() + + + + + + + + + + + + + ContextOrder + + + ContextOrder + + + + + + + + + - - + + + + + + getState() + + + - - + + + + + + setState(state) - - - - - __construct(order) + + - - - - - - - - - - - shipOrder() - - - - - - - - - completeOrder() - - - - - - - - - - - - - ShippingOrder - - - ShippingOrder - - - - - - - - + + + + + + done() + + + + + + + + + + getStatus() + + + + + + + + + + + + + ContextOrder + + + ContextOrder + + + + + + + + + +