首先,您需要一个状态管理器来处理状态:
<?php
class StateManager
{
protected $states = array();
public function registerState(StateInterface $state)
{
$this->states[$state->getName()] = $state;
}
public function getState($state)
{
if (!array_key_exists($state, $this->states)) {
throw new InvalidArgumentException();
}
return $this->states[$state];
}
}
然后你有一个可以对订单执行操作的订单管理器:
<?php
class OrderManager
{
protected $stateManager;
public function ship(OrderInterface $order)
{
try {
$this->stateManager->getState($order->getState())->ship($order);
} catch (OperationNotAllowedException $exception) {
// However you want to handle the fact that the state can't be shipped
}
}
}
如果订单在特定状态下无法执行操作,则会引发异常:
<?php
class OperationNotAllowedException extends Exception
{
}
状态接口:
<?php
interface StateInterface
{
public function getName();
// Then your normal functions
public function ship(OrderInterface $order);
public function cancel(OrderInterface $cancel);
public function addOrderLine(OrderInterface $order);
public function refund(OrderInterface $order);
}
现在,当您设置应用程序时:
$newOrderState = new NewState($database, $otherdependencies);
$stateManager->registerState($newOrderState);
您的订单对象仅返回其所在状态的字符串名称,该名称与该状态的getName
方法之一返回的名称相匹配。
此方法还允许轻松模拟和测试(这对于任何应用程序都很重要,尤其是处理人们的金钱和产品的电子商务)。