理解:当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
使用状态模式的场景:
对象中频繁改变非常依赖于条件语句。 就其自身来说, 条件语句本身没有什么问题(如switch语句或带else子句的语句),不过, 如果选项太多, 以到程序开始出现混乱, 或者增加或改变选项需要花费太多时间, 甚至成为一种负担, 这就出现了问题
对于状态设计模式, 每个状态都有自己的具体类, 它们实现一个公共接口. 我们不用查看对象的控制流, 而是从另一个角度来考虑, 即对象的状态.
状态机是一个模型, 其重点包括不同的状态, 一个状态到另一个状态的变迁, 以及导致状态改变的触发器.
eg:九宫格的移动,可以上下左右,当我们从一个格子移到另一个格子时,在移动时具体的状态就需要改变,比如,我们从5移动到4,再从4移动的时候就跟之前的5移动的具体情况不一样,比如4不能向左移动,所以到4后上下左右的发生的事件就需要变化,
下面代码具体实现思路,我们每次从一个格子移动到另一个格子时,其状态需要发生变化,实质改变了其实例化的类,所以当从5移动的时候调的是一个类,移动以后就会自动改变本身成移动后的状态类;
//每个格子移动可能移动的方法 interface IMatrix { public function goUp(); public function goDown(); public function goLeft(); public function goRight(); } class Context { private $cell1; private $cell2; private $cell3; private $cell4; private $cell5; private $cell6; private $cell7; private $cell8; private $cell9; private $currentState;//这个必须设置为私有,防止外界修改,这个是存储我们当前的状态,后面的操作都是在操作当前状态。 public function __construct() { //每一个但单元格都是一个类,实例化是引用其本身就是为了后面返回其本身; $this->cell1 = new Cell1State($this); $this->cell2 = new Cell2State($this); $this->cell3 = new Cell3State($this); $this->cell4 = new Cell4State($this); $this->cell5 = new Cell5State($this); $this->cell6 = new Cell6State($this); $this->cell7 = new Cell7State($this); $this->cell8 = new Cell8State($this); $this->cell9 = new Cell9State($this); $this->currentState = $this->cell5; } //调用方法,调用具体我们该走的步 public function doUp() { $this->currentState->goUp(); } public function doDown() { $this->currentState->goDown(); } public function doLeft() { $this->currentState->goLeft(); } public function doRight() { $this->currentState->goRight(); } //设置当前状态 public function setState(IMatrix $state) { $this->currentState = $state; } //获取状态 public function getCell1State() { return $this->cell1; } public function getCell2State() { return $this->cell2; } public function getCell3State() { return $this->cell3; } public function getCell4State() { return $this->cell4; } public function getCell5State() { return $this->cell5; } public function getCell6State() { return $this->cell6; } public function getCell7State() { return $this->cell7; } public function getCell8State() { return $this->cell8; } public function getCell9State() { return $this->cell9; } } class Cell1State implements IMatrix { private $context; public function __construct(Context $contextNow) { $this->context = $contextNow; } public function goLeft() { echo '不合法的移动!<br />'; } public function goRight() { echo '走到<strong>2</strong><br />'; $this->context->setState($this->context->getCell2State()); } public function goUp() { echo '不合法的移动!<br />'; } public function goDown() { echo '走到<strong>4</strong><br />'; $this->context->setState($this->context->getCell4State()); } } class Cell2State implements IMatrix { private $context; public function __construct(Context $contextNow) { $this->context = $contextNow; } public function goLeft() { echo '走到<strong>1</strong><br />'; $this->context->setState($this->context->getCell1State()); } public function goRight() { echo '走到<strong>3</strong><br />'; $this->context->setState($this->context->getCell3State()); } public function goUp() { echo '不合法的移动!<br />'; } public function goDown() { echo '走到<strong>5</strong><br />'; $this->context->setState($this->context->getCell5State()); } } class Cell3State implements IMatrix { private $context; public function __construct(Context $contextNow) { $this->context = $contextNow; } public function goLeft() { echo '走到<strong>2</strong><br />'; $this->context->setState($this->context->getCell2State()); } public function goRight() { echo '不合法的移动!<br />'; } public function goUp() { echo '不合法的移动!<br />'; } public function goDown() { echo '走到<strong>6</strong><br />'; $this->context->setState($this->context->getCell6State()); } } class Cell4State implements IMatrix { private $context; public function __construct(Context $contextNow) { $this->context = $contextNow; } public function goLeft() { echo '不合法的移动!<br />'; } public function goRight() { echo '走到<strong>5</strong><br />'; $this->context->setState($this->context->getCell5State()); } public function goUp() { echo '走到<strong>1</strong><br />'; $this->context->setState($this->context->getCell1State()); } public function goDown() { echo '走到<strong>7</strong><br />'; $this->context->setState($this->context->getCell7State()); } } class Cell5State implements IMatrix { private $context; public function __construct(Context $contextNow) { $this->context = $contextNow; } public function goLeft() { echo '走到<strong>4</strong><br />'; $this->context->setState($this->context->getCell4State()); } public function goRight() { echo '走到<strong>6</strong><br />'; $this->context->setState($this->context->getCell6State()); } public function goUp() { echo '走到<strong>2</strong><br />'; $this->context->setState($this->context->getCell2State()); } public function goDown() { echo '走到<strong>8</strong><br />'; $this->context->setState($this->context->getCell8State()); } } class Cell6State implements IMatrix { private $context; public function __construct(Context $contextNow) { $this->context = $contextNow; } public function goLeft() { echo '走到<strong>5</strong><br />'; $this->context->setState($this->context->getCell5State()); } public function goRight() { echo '不合法的移动!<br />'; } public function goUp() { echo '走到<strong>3</strong><br />'; $this->context->setState($this->context->getCell3State()); } public function goDown() { echo '走到<strong>9</strong><br />'; $this->context->setState($this->context->getCell9State()); } } class Cell7State implements IMatrix { private $context; public function __construct(Context $contextNow) { $this->context = $contextNow; } public function goLeft() { echo '不合法的移动!<br />'; } public function goRight() { echo '走到<strong>8</strong><br />'; $this->context->setState($this->context->getCell8State()); } public function goUp() { echo '走到<strong>4</strong><br />'; $this->context->setState($this->context->getCell4State()); } public function goDown() { echo '不合法的移动!<br />'; } } class Cell8State implements IMatrix { private $context; public function __construct(Context $contextNow) { $this->context = $contextNow; } public function goLeft() { echo '走到<strong>7</strong><br />'; $this->context->setState($this->context->getCell7State()); } public function goRight() { echo '走到<strong>9</strong><br />'; $this->context->setState($this->context->getCell9State()); } public function goUp() { echo '走到<strong>5</strong><br />'; $this->context->setState($this->context->getCell5State()); } public function goDown() { echo '不合法的移动!<br />'; } } class Cell9State implements IMatrix { private $context; public function __construct(Context $contextNow) { $this->context = $contextNow; } public function goLeft() { echo '走到<strong>8</strong><br />'; $this->context->setState($this->context->getCell8State()); } public function goRight() { echo '不合法的移动!<br />'; } public function goUp() { echo '走到<strong>6</strong><br />'; $this->context->setState($this->context->getCell6State()); } public function goDown() { echo '不合法的移动!<br />'; } } class Client { private $context; public function __construct() { $this->context = new Context(); $this->context->doUp();//状态到2---走到2 $this->context->doRight();//状态到3---走到3 $this->context->doDown();//状态到6---走到6 $this->context->doDown();//状态到9---走到9 $this->context->doLeft();//状态到8---走到8 $this->context->doUp();//状态到5---走到5 } } $worker = new Client();
再比如灯的开关不同的状态:
class Light { private $offState; //关闭状态 private $onState; //开启状态 private $currentState; //当前状态 public function __construct() { $this->offState = new OffState($this); $this->onState = new OnState($this); //开始状态为关闭状态Off $this->currentState = $this->offState; } //调用状态方法触发器 public function turnLightOn() { $this->currentState->turnLightOn(); } public function turnLightOff() { $this->currentState->turnLightOff(); } //设置当前状态 public function setState(IState $state) { $this->currentState = $state; } //获取状态 public function getOnState() { return $this->onState; } public function getOffState() { return $this->offState; } } interface IState { public function turnLightOn(); public function turnLightOff(); } class OnState implements IState { private $light; public function __construct(Light $light) { $this->light = $light; } public function turnLightOn() { echo "开灯,灯现在就是开的,所以不需要在设置状态,不做任何操作。<br/>"; } public function turnLightOff() { echo "灯关闭!我现在需要把我的状态改为关闭!<br/>"; $this->light->setState($this->light->getOffState()); } } class OffState implements IState { private $light; public function __construct(Light $light) { $this->light = $light; } public function turnLightOn() { echo "灯打开!我现在需要把状态改为开,!<br/>"; $this->light->setState($this->light->getOnState()); } public function turnLightOff() { echo "关灯,灯现在就是关的,所以不需要在设置状态,不做任何操作。<br/>"; } } class Client { private $light; public function __construct() { $this->light = new Light(); $this->light->turnLightOn();//灯打开!我现在需要把状态改为开,! $this->light->turnLightOn();//开灯,灯现在就是开的,所以不需要在设置状态,不做任何操作。 $this->light->turnLightOff();//灯关闭!我现在需要把我的状态改为关闭! $this->light->turnLightOff();//关灯,灯现在就是关的,所以不需要在设置状态,不做任何操作。 $this->light->turnLightOn();//灯打开!我现在需要把状态改为开,! $this->light->turnLightOn();//开灯,灯现在就是开的,所以不需要在设置状态,不做任何操作 $this->light->turnLightOn();//开灯,灯现在就是开的,所以不需要在设置状态,不做任何操作 } } $worker = new Client();