State 状态模式可以基于一个对象的同种事务而封装出不同的行为
它提供一种简洁的方式使得对象在运行时可以改变自身行为,而不必借助单一庞大的条件判断语句
以前在做一个商城中的订单时,设计的订单类大致意思如下:
class Order
{
private $state;
const UN_PAY_STATE = 0;
const PAY_STATE = 1;
const EVALUATE_STATE = 2;
const FINISH_STATE = 3;
public function handle()
{
switch ($this->state) {
case self::UN_PAY_STATE:
//客户新建订单,是未付款
break;
case self::PAY_STATE:
//客户未付款,要收钱
break;
case self::EVALUATE_STATE:
//客户已付款,要评价
break;
case self::FINISH_STATE:
//客户已评价,订单完成
break;
}
}
}
单独状态单独处理,手动设置状态,非常僵硬:
$order = new Order();
$order->setState(Order::PAY_STATE);
$order->handle();
下面用状态模式替代,已付款状态的例子:
State 接口规定了
doAction(Order $order)
PayState.phpclass PayState implements State { const STATE = 1; public function doAction(Order $order) { if (self::STATE === $order->getCurrentState()) { //调用API收钱 } else { //转向下一个评价状态 $order->setState(new EvaluateState()); $order->handle(); } } }
原来的订单类中需要加上新属性: $currentState
,存放当前状态
而原来的 $state
属性存放的就不是值了,而是一个状态对象:
Order.phpclass Order { private $state; private $currentState; public function __construct() { $this->state = new UnPayState(); $this->currentState = UnPayState::STATE; } public function handle() { $this->state->doAction($this); } }