状态模式是行为模式的一种,其主要特点是对象的状态发生改时对象的行为也会随之发生改变,换而言之一旦你的代码中涉及了复杂状态切换且这种切换且这种切换带来的行为不同时你就该考虑使用状态模式了。
为什么要使用状态设计模式
使用状态模式的好处是不言而喻的,试想一下你的系统必须依据不同状况做出不同的处理响应,在传统的程序开发过程中为了应对这种情况你不得不使用大量的 if...else 来对这些状态进行区分处理。然而在复杂的状态处理上这种处理方式的弊端也是显而易见的,一方面大量 if...else 的散落带来了代码可读性的降低,另外在新增或者修改时将会变得非常的困难,代码的可维护性变得非常的脆弱。而使用状态设计模式时你只需将不同状态的行为进行封装,在状态发生变更时调用封装类库传入当前的状态即可。
状态设计模式的的具体适用场景
应该使用状态设计模式最直观的表现是,你的对象中出现了大量的 if...elseif...else 分支或者出现了类似于 switch case 分支类型且你分支类型依赖于该对象的状态,而且往往伴随着你的其他操作中还包含了大量同样判断。
状态设计模式的三部分组成。
- 上线文环境类:这个类负责维护跟踪状态类的实例,并且提供操作状态实例的方法和客户端可能用到的一些获取状态实例功能方法。
- 状态类契约(接口):这个类定义了状态类共有的必须实现的一些行为方法。
- 状态接口的实现:这些类时是体状态的拆分,他实现了具体状态的具体行为。
状态类的示例
这里以电灯的开关状态来举例:
php
/**
* 状态类契约
* Interface State
*/
interface State
{
/**
* 开灯
* @date 2019/10/13 10:12 下午
* @return mixed
*/
public function turnLightOn();
/**
* 关灯
* @date 2019/10/13 10:12 下午
* @return mixed
*/
public function turnLightOff();
}
/**
* 状态契约的开灯实现
* Class OnState
*/
class OnState implements State
{
/**
* @var Context
*/
private $context;
public function __construct(Context $context)
{
$this->context = $context;
}
public function turnLightOn()
{
//light is already on doing noting
}
public function turnLightOff()
{
$this->context->setCurrentState($this->context->getOnState());
}
}
/**
* 状态类的关灯实现
* Class OffState
*/
class OffState implements State
{
/**
* @var Context
*/
private $context;
public function __construct(Context $context)
{
$this->context = $context;
}
public function turnLightOn()
{
$this->context->setCurrentState($this->context->getOffState());
}
public function turnLightOff()
{
//light is already off doing noting
}
}
/**
* 上下文追踪类,跟踪对象所处的状态
* Class Context
*/
class Context
{
/**
* @var OnState
*/
private $onState;
/**
* @var OffState
*/
private $offState;
/**
* @var State
*/
private $currentState;
public function __construct()
{
$this->onState = new OnState($this);
$this->offState = new OffState($this);
//设置初识状态为关闭状态
$this->currentState = $this->offState;
}
public function turnLightOn()
{
return $this->currentState->turnLightOn();
}
public function turnLightOff()
{
return $this->currentState->turnLightOff();
}
public function setCurrentState(State $state)
{
$this->currentState = $state;
}
public function getOnState()
{
return $this->onState;
}
public function getOffState()
{
return $this->offState;
}
}