什么是状态设计模式
类图如下:
状态设计模式
这个可以理解为对象行为随着状态改变的一个设计模式
如,随着四季变化,树的行为也跟着变化。
随着开关的变化,灯泡的行为也跟着变化。
为什么要使用
在软件设计过程中,对象的状态可能是会发生改变的,当对象的状态改变之后,我们可以使用 if
或者 switch
语句来判断对象的行为,但是如果对象的状态特别多的话,就会发生一个问题,对象的状态增加修改之后会频繁修改原来的类。
使用状态设计模式时,允许一个对象在其内部状态改变时改变它的行为。
类型
行为型模式
参与者
-
Context 上下文类
- 维护一个具体状态角色ConcreteState的实例,这个实例定义当前状态。
-
IState 抽象状态类
- 声明了各种不同状态对应的方法。
-
ConcreteState 具体状态类
- 每一个实现一个与Context的一个状态相关的行为。
例子
只有两种状态的灯泡
代码中 Light 代表 Context 上下文类
<?php
/**
* 只有两种状态的灯泡,可以开启和关闭
*/
/**
* 灯
*/
class Light
{
private $offState;
private $onState;
/**
* @var IState
*/
private $currentState;
public function __construct()
{
$this->offState = new offState($this);
$this->onState = new onState($this);
$this->currentState = $this->offState;
}
public function turnOn()
{
$this->currentState->turnOn();
}
public function turnOff()
{
$this->currentState->turnOff();
}
public function setState(IState $state)
{
$this->currentState = $state;
}
public function getOnState()
{
return $this->onState;
}
public function getOffState()
{
return $this->offState;
}
}
interface IState
{
public function turnOn();
public function turnOff();
}
/**
* 灯的关闭状态
*/
class offState implements IState
{
private $context;
public function __construct(Light $light)
{
$this->context = $light;
}
public function turnOff()
{
echo 'light is already **off**, please chose another operation'.PHP_EOL;
}
public function turnOn()
{
echo 'light on!'.PHP_EOL;
$this->context->setState($this->context->getOnState());
}
}
/**
* 灯的开启状态
*/
class onState implements IState
{
private $context;
public function __construct(Light $light)
{
$this->context = $light;
}
public function turnOff()
{
echo 'light off!'.PHP_EOL;
$this->context->setState($this->context->getOffState());
}
public function turnOn()
{
echo 'light is already **on**, please chose another operation'.PHP_EOL;
}
}
class Client
{
private $light;
public function __construct()
{
$this->light = new Light();
$this->light->turnOn();
$this->light->turnOn();
$this->light->turnOff();
$this->light->turnOff();
}
}
$client = new Client();
新增加一种损坏状态
<?php
// 状态模式设计方法
/**
* 灯
*/
class Light
{
private $offState;
private $onState;
private $brokenState;
/**
* @var IState
*/
private $currentState;
public function __construct()
{
$this->offState = new offState($this);
$this->onState = new onState($this);
$this->brokenState = new brokenState();
$this->currentState = $this->offState;
}
public function turnOn()
{
$this->currentState->turnOn();
}
public function turnOff()
{
$this->currentState->turnOff();
}
public function brokeIt()
{
$this->currentState->turnBroken();
}
public function setState(IState $state)
{
$this->currentState = $state;
}
public function getOnState()
{
return $this->onState;
}
public function getOffState()
{
return $this->offState;
}
public function getBrokeState()
{
return $this->brokenState;
}
}
interface IState
{
public function turnOn();
public function turnOff();
public function turnBroken();
}
/**
* 灯的关闭状态
*/
class offState implements IState
{
private $context;
public function __construct(Light $light)
{
$this->context = $light;
}
public function turnOff()
{
echo 'light is already **off**, please chose another operation'.PHP_EOL;
}
public function turnOn()
{
echo 'light on!'.PHP_EOL;
$this->context->setState($this->context->getOnState());
}
public function turnBroken()
{
echo 'light is broke now'.PHP_EOL;
$this->context->setState($this->context->getBrokeState());
}
}
/**
* 灯的开启状态
*/
class onState implements IState
{
private $context;
public function __construct(Light $light)
{
$this->context = $light;
}
public function turnOff()
{
echo 'light off!'.PHP_EOL;
$this->context->setState($this->context->getOffState());
}
public function turnOn()
{
echo 'light is already **on**, please chose another operation'.PHP_EOL;
}
public function turnBroken()
{
echo 'light broken now'.PHP_EOL;
$this->context->setState($this->context->getBrokeState());
}
}
/**
* 新增一个损坏状态
*
* Class brokenState
*/
class brokenState implements IState
{
public function turnOn()
{
echo 'light is broken, can not open now'.PHP_EOL;
}
public function turnOff()
{
echo 'light is already off, because it is broken.'.PHP_EOL;
}
public function turnBroken()
{
echo 'light is already broken.'.PHP_EOL;
}
}
/**
* Class Client
*/
class Client
{
private $light;
public function __construct()
{
$this->light = new Light();
$this->light->turnOn();
$this->light->turnOn();
$this->light->turnOff();
$this->light->turnOff();
$this->light->brokeIt();
$this->light->turnOn();
$this->light->turnOff();
}
}
$client = new Client();
light on!
light is already **on**, please chose another operation
light off!
light is already **off**, please chose another operation
light is broke now
light is broken, can not open now
light is already off, because it is broken.
网友评论