purpose
State mode can encapsulate different behaviors based on the same kind of transaction of an object. It provides a concise way for an object to change its behavior at runtime without having to resort to a single large conditional judgment statement.
UML graphics
Code
- ContextOrder.php
<?php
namespace DesignPatterns\Behavioral\State;
class ContextOrder extends StateOrder
{
public function getState():StateOrder
{
return static::$state;
}
public function setState(StateOrder $state)
{
static::$state = $state;
}
public function done()
{
static::$state->done();
}
public function getStatus(): string
{
return static::$state->getStatus();
}
}
- StateOrder.php
<?php
namespace DesignPatterns\Behavioral\State;
abstract class StateOrder
{
/**
* @var array
*/
private $details;
/**
* @var StateOrder $state
*/
protected static $state;
/**
* @return mixed
*/
abstract protected function done();
protected function setStatus(string $status)
{
$this->details['status'] = $status;
$this->details['updatedTime'] = time();
}
protected function getStatus(): string
{
return $this->details['status'];
}
}
- ShippingOrder.php
<?php
namespace DesignPatterns\Behavioral\State;
class ShippingOrder extends StateOrder
{
public function __construct()
{
$this->setStatus('shipping');
}
protected function done()
{
$this->setStatus('completed');
}
}
- CreateOrder.php
<?php
namespace DesignPatterns\Behavioral\State;
class CreateOrder extends StateOrder
{
public function __construct()
{
$this->setStatus('created');
}
protected function done()
{
static::$state = new ShippingOrder();
}
}
test
- Tests/StateTest.php
<?php
namespace DesignPatterns\Behavioral\State\Tests;
use DesignPatterns\Behavioral\State\ContextOrder;
use DesignPatterns\Behavioral\State\CreateOrder;
use DesignPatterns\Behavioral\State\ShippingOrder;
use PHPUnit\Framework\TestCase;
class StateTest extends TestCase
{
public function testCanShipCreatedOrder()
{
$order = new CreateOrder();
$contextOrder = new ContextOrder();
$contextOrder->setState($order);
$contextOrder->done();
$this->assertEquals('shipping', $contextOrder->getStatus());
}
public function testCanCompleteShippedOrder()
{
$order = new ShippingOrder();
$contextOrder = new ContextOrder();
$contextOrder->setState($order);
$contextOrder->done();
$this->assertEquals('completed', $contextOrder->getStatus());
}
}
The Growth Path of PHP Internet Architect * The Ultimate Guide to "Design Patterns"
PHP Internet Architect 50K Growth Guide + Industry Problem Solving Guide (Continuous Update)
Interview with 10 companies, get 9 offers, PHP interview questions in 2020
★If you like my article and want to communicate and learn with more senior developers, get more technical consultation and guidance related to interviews with big factories, welcome to join our group, password: phpzh (Junyang number 856460874).
The latest PHP advanced tutorial in 2020, full series!
If the content is good, I hope everyone will support and encourage you to give a like/like, and welcome to communicate together; in addition, if you have any questions, you can suggest what you want to see in the comments.