行云流水's Bolg

第十章:状态模式 - Head First 设计模式

状态模式

状态模式允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。

这个模式将状态封装成为独立的类,并将动作委托到代表当前状态的对象,于是类的行为随着内部状态改变而改变。

糖果机售卖机例子中是状态决定了下一个状态是什么,通常,当状态转换是固定的时候,就适合放在Context中,当状态转换更动态时,通常就会放在状态类中。
将状态转换放在状态类中的缺点:状态类之间产生了依赖,在下面的例子中,我们通过使用Context上的getter方法把依赖减到最小,而不是显示硬编码具体状态类。
状态转换在哪里,这也决定了,当系统进化时,究竟哪个类是对修改封闭的(Context还是状态类)。(p412)

模式类图:p410图

p410图

例子:糖果机售卖机

不好的设计1:传统的容易想到的状态判断式结构

p390,391代码

缺点:繁杂,且难以扩展和修改,美柚遵守开放-关闭原则,不符合面向对象,没有封装变化点。

p390图

p391图

状态模式的设计:

状态接口和类:p399图

p399图

实现状态类,比如SoldState[卖出(正要出糖)状态]:p405代码

p405图

售卖机实现:p403代码

p403图

状态模式与策略模式的区别

两个模式类图一样,差别在于意图不同。

状态模式:将一群行为封装在状态对象中,时间流逝,当前状态在状态对象集合中游走改变,但是context的客户浑然不觉。

策略模式:客户通常主动指定Context所要组合的策略对象。虽然策略模式和状态模式一样能在运行时改变策略,但是对于某个context,通常只有一个最适当的策略,比如野鸭能高飞,而家鸭只能紧贴地面飞行。

设计层面

策略模式一般被视为除继承外的一种弹性替代方案。如果你使用继承定义了一个类的行为,那么你将被这个行为困住,甚至要修改都难。通过策略模式,就可以通过组合不同的对象来改变行为。

状态模式可以看成是不用在context中防止许多条件判断的替代方案。通过将行为包装进状态对象中,就可以在context内简单改变状态来改变context行为。

连连看

  1. 状态模式:封装基于状态的行为,并将行为委托到当前状态。
  2. 策略模式:将可以互换的行为封装起来,然后使用委托的方法,决定使用哪一个行为。
  3. 模板方法:有子类决定如何实现算法中的某些步骤。
blog comments powered by Disqus