状态模式:通过改变对象内部的状态,来帮助对象控制自己的行为。
策略模式:围绕可以互换的算法来成功业务的
每一个装填都代表机器不同的配置以某种方式行动,需要某些动作将目前的状态转换到另一个状态。
1. 实现状态机
[1] 找出所有状态
没有25分钱 有25分钱 糖果售罄 售出糖果
[2] 创建一个实例变量持有目前的状态,定义每个状态的值
final static int SOLD_OUT = 0;
final static int NO_QUARTER = 1;
final static int HAS_QUARTER = 2;
final static int SOLD = 3;
[3] 将系统中可以发生的动作整合起来
投入25分钱 退回25分钱 转动曲柄 发放糖果
[4] 创建一个类,就像一个状态机。每个动作,创建一个对应的方法
public void insertQuarter(){
if(state == HAS_QUARTER){
System.out.println("You can't insert another quarter");
}else if (state == NO_QUARTER){
state = HAS_QUARTER;
System.out.println("You insert a quarter");
}else if(state == SOLD_OUT){
System.out.println("You can't insert a quarter, the machine is sold out");
}else if (state == SOLD){
System.out.println("Please wait, we're already giving you a gumball");
}
}
[5] 若处理这个十次赢一次的竞赛
首先,必须加一个新的状态,为“赢家”
每个方法中加入一个新的条件判断来处理“赢家”状态
turnCrank()一团乱,必须检测是否是赢家,再决定切换到赢家状态还是售出糖果状态
2. 局部化每个状态的行为,遵守“封装变化”原则
多用组合,少用继承
[1] 首先,定义一个state接口,在接口内,每个动作都有一个对应的方法
[2] 为机器中的每个状态实现状态类,这些类负责在对应的状态下进行机器的行为
[3] 摆脱旧的条件代码,取而代之的是,将动作委托到状态类
3. 定义状态接口和类
将每个状态的行为局部化到它自己的类中
将容易产生问题的if语句删除,以方便日后的维护
让每一个状态“对修改关闭“,让糖果机”对扩展开放“
4. 状态模式:允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类
状态封装为独立的类,并将动作委托到代表当前按状态的对象,行为随着内部状态而改变。
使用组合通过简单引用不同的状态对象来造成类改变的假象
Context可以有多个实例,共享状态对象,需要把每个状态都指定到静态的实例变量中
状态间产生了依赖,这里用context的getter方法把依赖减到最小,而不是硬编码
5. 当有抽中者时,增加状态类 winnerState, 而不是直接在SoldState中加入发放两颗糖果的代码
一个类,一个责任;
牺牲了状态类的清晰易懂减少一些冗余代码
促销方案结束或赢家的几率改变
状态模式:改变行为,建立在方案中
策略模式:控制对象使用什么策略