状态模式又称为:State。状态是一种行为设计模式,能在一个对象的内部状态变化时改变其行为,使其看上去就像改变了自身所属的类一样。
有一个 文档 Document 类。 文档可能会处于 草稿(Draft) 、 审阅中 (Moderation)和 已发布(Published)三种状态中的一种。
文档的 发布(publish)方法在不同状态下的行为略有不同:
平常可能会直接将状态转换的操作写到一个方法中
switch ($status) {
case 'Draft':
break;
case 'Moderation':
break;
case 'Published':
break;
}
PHP
Copy
为了能根据当前状态选择完成相应行为的方法,绝大部分方法中会包含复杂的条件语句。修改其转换逻辑可能会涉及到修改所有方法中的状态条件语句,导致代码的维护工作非常艰难。这个问题会随着项目进行变得越发严重。我们很难在设计阶段预测到所有可能的状态和转换。随着时间推移,最初仅包 含有限条件语句的简洁状态机可能会变成臃肿的一团乱麻。
我们将工作委派给一个状态对象。将所有可能状态新建一个类,然后将所有状态的对应行为抽取到这些类中。也就是说我们把具体的转化过程交个具体的状态类,而无需到使用状态的类中编写。
原始对象被称为上下文(context),它并不会自行实现所有行为,而是会保存一个指向表示当前状态的状态对象的引用,且将所有与状态相关的工作委派给该对象。
State:状态基类; Draft : 实现 State 接口的具体状态类; Document:具体的使用状态模式类 ;
abstract class State
{
/**
* 当前类
* @var Document
*/
public Document $document;
public function __construct(Document $document)
{
$this->document = $document;
}
/**
* 渲染
* @return mixed
* @author chendashengpc
*/
abstract public function render();
/**
* 发布
* @return mixed
* @author chendashengpc
*/
abstract public function publish();
}
PHP
Copy
草稿
/**
* 草稿
*/
class Draft extends State
{
public function render()
{
return '草稿状态';
}
/**
* 发布为审核中
* @return mixed|void
* @author chendashengpc
*/
public function publish()
{
$this->document->changeState(new Moderation($this->document));
}
}
PHP
Copy
审查中
/**
* 审查中
*/
class Moderation extends State
{
public function render()
{
return '审查状态';
}
/**
* 发布为审核中
* @return mixed|void
* @author chendashengpc
*/
public function publish()
{
$this->document->changeState(new Published($this->document));
}
}
PHP
Copy
已发表
/**
* 已发表
*/
class Published extends State
{
public function render()
{
return '已发表状态';
}
/**
* 发布成功了,再次可变为草稿
* @return mixed|void
* @author chendashengpc
*/
public function publish()
{
$this->document->changeState(new Draft($this->document));
}
}
PHP
Copy
class Document
{
protected State $state;
/**
* 初始化默认状态
*/
public function __construct()
{
$this->state = new Draft($this);
}
/**
* 渲染
* @return void
* @author chendashengpc
*/
public function render()
{
return $this->state->render();
}
/**
* 发布
* @return void
* @author chendashengpc
*/
public function publish()
{
return $this->state->publish();
}
/**
* 修改状态
* @param State $state
* @return void
* @author chendashengpc
*/
public function changeState(State $state)
{
$this->state = $state;
}
}
PHP
Copy
$document = new Document();
// 处于草稿阶段
echo $document->render() . PHP_EOL;
// 发布为审核状态
$document->publish();
echo $document->render() . PHP_EOL;
// 发布
$document->publish();
echo $document->render() . PHP_EOL;
PHP
Copy
输出
草稿状态
审查状态
已发表状态