Head First 设计模式 --10 状态模式
Posted bad_boy_f
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Head First 设计模式 --10 状态模式相关的知识,希望对你有一定的参考价值。
状态模式:允许对象在内部状态改变时改变他的行为,对象看起来好像修改了他的类。
用到的设计原则
1、封装变化
2、多用组合,少用继承
3、针对接口编程,不针对实现编程
4、松耦合
5、对扩展开放,对修改关闭
6、依赖抽象,而不依赖具体
7、只和朋友交谈
8、别找我,我会找你
9、类应该只有一个修改的理由
例子来自《Head First设计模式》,糖果机的例子
interface State { public void insertQuarter(); public void ejectQuarter(); public void turnCrank(); public void dispense(); } class NoQuarterState implements State { GumballMachine gumballMachine; public NoQuarterState(GumballMachine gumballMachine) { this.gumballMachine = gumballMachine; } public void insertQuarter() { System.out.println("You inserted a quarter"); gumballMachine.setState(gumballMachine.hasQuarterState); } public void ejectQuarter() { System.out.println("You haven\'t inserted a quarter"); } public void turnCrank() { System.out.println("You turned, but there\'s no quarter"); } public void dispense() { System.out.println("You need to pay first"); } public String toString() { return "waiting for quarter"; } } class HasQuarterState implements State { Random randomWinner = new Random(System.currentTimeMillis()); GumballMachine gumballMachine; public HasQuarterState(GumballMachine gumballMachine) { this.gumballMachine = gumballMachine; } public void insertQuarter() { System.out.println("You can\'t insert another quarter"); } public void ejectQuarter() { System.out.println("Quarter returned"); gumballMachine.setState(gumballMachine.noQuarterState); } public void turnCrank() { System.out.println("You turned..."); int winner = randomWinner.nextInt(10); if ((winner == 0) && (gumballMachine.count > 1)) { gumballMachine.setState(gumballMachine.winnerState); } else { gumballMachine.setState(gumballMachine.soldOutState); } } public void dispense() { System.out.println("No gumball dispensed"); } public String toString() { return "waiting for turn of crank"; } } class GumballMachine { State soldOutState; State noQuarterState; State hasQuarterState; State soldState; State winnerState; State state = soldOutState; int count = 0; public GumballMachine(int numberGumballs) {// soldOutState = new SoldOutState(this); noQuarterState = new NoQuarterState(this); hasQuarterState = new HasQuarterState(this); // soldState = new SoldState(this); // winnerState = new WinnerState(this); this.count = numberGumballs; if (numberGumballs > 0) { state = noQuarterState; } } public void insertQuarter() { state.insertQuarter(); } public void ejectQuarter() { state.ejectQuarter(); } public void turnCrank() { state.turnCrank(); state.dispense(); } void setState(State state) { this.state = state; } void releaseBall() { System.out.println("A gumball comes rolling out the slot..."); if (count != 0) { count = count - 1; } } } public class StateTest { public static void main(String[] args) { GumballMachine gumballMachine = new GumballMachine(10); gumballMachine.insertQuarter(); gumballMachine.turnCrank(); gumballMachine.insertQuarter(); gumballMachine.turnCrank(); } }
类图:
上面的代码运行不了。缺少三种State,这里只是看一下要表达的意思。
装填模式将状态封装成独立的类,并将每个动作委托给当前状态的对象。如果对象能够完全改变它的行为,那么你会觉得,这个对象实际是从别的类实例化出来的,而实际上,我们是用组合通过简单引用不同的状态对象来造成类的改变的假象。
当我们看到上面的类图时,会发现这个类图和策略模式的类图是一样的。
策略模式:我们将一群行为封装在状态对象中,context的行为随时可委托到哪个状态对象中。随着状态的改变,以反应context的内部的状态。但是context的客户对于状态对象了解不多。状态模式代替多条件判断的设计方案,通过包装状态对象,在context内简单地改变状态对象。
装填模式:通常是主动指定context所要组合的对象是哪一个。这个对象一般情况不会改变,因为对于程序而言,他就是这个类型的,具有特定的行为。一般来说,策略模式是除了继承外一种弹性的设计方案。
状态模式:封装基于装填的行为,并将行为委托到当前状态
策略模式:将可以减缓的行为封装起来,然后使用委托的方法决定使用那一个行为
模板方法模式:由子类决定如何实现算法中的某个步骤
以上是关于Head First 设计模式 --10 状态模式的主要内容,如果未能解决你的问题,请参考以下文章