组合 、委托
基本常识:策略模式和状态模式是双胞胎,在出生时才分开。
一般来说,我们把策略模式想成是除了继承之外的一种弹性替代方案。
什么时候用接口? or 抽象类?
当实现接口的类中,重复代码太多时,可考虑继承 。
OO模式:
状态模式--允许对象在内部状态改变时改变它的作为,对象看起来好像修改了它的类
如: 因为一个状态对应一个类, 每个类中的方法名相同,但实现不同。 所以看起来好像修改了类。
例:
饮料机(DrinkMachine)的状态
如果对对象的状态建模 -- 通过创建一个实例变量来持有状态值,并在方法内书写条件代码来处理不同状态。
状态:投币、出饮料、退币、售完饮料等
public class DrinkMachine{
final static int SOLD_OUT=0; //卖出
final static int NO_QUARTER =1; //没有25分钱
final static int HAS_QUARTER = 2; // 有 25分钱
final staic int SOLD =3;
int state = SOLD_OUT ; // 初始状态饮料售罄
int count = 0; //机器内 饮料数量
public DrinkMachine(int count ){ //初始化饮料数量
this.count = count;
if(count <0){
state = NO_QUARTER;
}
}
public void insertQuarter(){ // 投币动作
if(state == HAS_QUARTER){}
else if( state ==NO_QUARTER){} //跟据当前不同的状态 , 做相应的事。
else if( state ==SOLD_OUT){}
}
// 退币动作
// 转动手柄 取饮料动作
// 出饮料动作
} //
如果变更需求时 (如新加一个随机出两瓶饮料的动作),将 不容易 扩展。 需要修改类的方法 , 违返 设计原则 对修改关闭。
使用思虑周密的方法学构造的牢不可破的设计
新的设计: 组合 委托
将状态对象封装在各自的类中,然后在动作发生时委托给当前状态
(1)首先,我们定义一个State接口。在这个接口内,糖果机的每个动作都有一个对应的方法。
(2) 然后为机器中的每个状态实现状状类。这些类将负责在对应的状态下进行机器的行为。
(3)最后,我们要摆脱旧的条件代码,取而代之的方式是,将动作委托到状态类。
之前的 饮料机中每一个状态 对应 现在的一个状态类。
下面就是完成各种状态类。 implements State 如: 投币之后,应该做哪些事,机器到什么状态
一个类一个责任,莫要用一个类表示两个状态。
状态: 封装基于状态的行为,并将行为委托到当前状态。
策略:将可以互换的行为封装起来,然后使用委托的方法,决定使用哪一个行为。
模板方法:由子类决定如何实现算法中的某些步聚。
要点:
(1)状态模式允许一个对象基于内部状态而拥有不同的行为。
(2)和程序状态机(PSM)不同,状态模式用类代表状态。
(3)Context 会将行为委托给当前状态对象。
(4)通过将每个状态封装进一个类,我们把以后需要做的任何改变局部化了。
(5)状态模式和策略模式有相同的类图,但是它们的意思不同。
(6)策略模式通用会用行为或算法来配置Context类。
(7)状态模式允许Context随着状态的改变而改变行为。
(8)使用状态模式通常会导致设计中类的数目大量增加
(9)状态类可以被多个Context实例共享。
设计模式(10)--状态模式