HeadFirst 设计模式 10状态模式(糖果机)
来源:互联网 发布:投影机网络控制软件 编辑:程序博客网 时间:2024/05/17 23:55
状态模式
允许对象在内部状态改变是改变它的行为,对象看起来好像修改了它的类。
第一句指:该模式将状态封装成为独立的类,并将动作委托到代表当前状态的对象,且行为会随着内部状态而改变。
“看起来好像修改了它的类”指从客户的角度看:若你说使用的对象能够完全改变他的行为,那么你会觉得,这个对象实际上是从别的类实例化而来的。然后实际上,是在使用组合通过简单引用不同的状态对象来造成改变的假象。
糖果机实例
//没有硬币状态public class NoQuarterState implements State{ GumballMachine gumballMachine; //通过构造器得到糖果机的引用,然后将它记录在实例变量中 public NoQuarterState(GumballMachine gumballMachine){ this.gumballMachine=gumballMachine; } //有人投币,改变机器状态到HasQuarterState public void insertQuater(){ System.out.println("You insert a quater"); gumballMachine.setState(gumballMachine.getHasQuarterState()); } //没给钱,不能要求退钱 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 class HasQuarterState implements State{ //增加一个随机数产生器,产生10%赢得机会 Random randomWinner= new Random(System.currentTimeMillis()); GumballMachine gumballMachine; //状态被实例化是,传入GumballMachine的引用作为参数 public HasQuarterState(GumballMachine gumballMachine){ this.gumballMachine=gumballMachine; } //不能连续投币两次 public void insertQuater(){ System.out.println("You can't insert another quater"); } //退钱,并将状态转到NoQuarterState public void ejectQuarter(){ System.out.println("Quarter returned"); gumballMachine.setState(gumballMachine.getNoQuarterState()); } //状态转到SoldState public void turnCrank(){ System.out.println("You turned..."); int winner=randomWinner.nextInt(10); if((winner==0)&&(gumballMachine.getCount()>1)){ gumballMachine.setState(gumballMachine.getWinnerState()); }else{ gumballMachine.setState(gumballMachine.getSoldState()); } } public void dispense(){ System.out.println("No gumball dispensed"); }}public class SoldState implements State{ GumballMachine gumballMachine; //状态被实例化是,传入GumballMachine的引用作为参数 public SoldState(GumballMachine gumballMachine){ this.gumballMachine=gumballMachine; } //以下的动作都不合法 public void insertQuater(){ System.out.println("Please wait,we're already giving you a gumball"); } public void ejectQuarter(){ System.out.println("Sorry,you already turned the crank"); } public void turnCrank(){ System.out.println("Turning twice doesn't get you another gumball"); } //发糖 public void dispense(){ gumballMachine.releaseBall(); if(gumballMachine.getCount()>0){ gumballMachine.setState(gumballMachine.getNoQuarterState()); }else{ System.out.println("Oops,out of gumball"); gumballMachine.setState(gumballMachine.getSoldOutState()); } }}public class WinnerState implements State{ GumballMachine gumballMachine; //状态被实例化是,传入GumballMachine的引用作为参数 public WinnerState(GumballMachine gumballMachine){ this.gumballMachine=gumballMachine; } //以下的动作都不合法 public void insertQuater(){ System.out.println("Please wait,we're already giving you a gumball"); } public void ejectQuarter(){ System.out.println("Sorry,you already turned the crank"); } public void turnCrank(){ System.out.println("Turning twice doesn't get you another gumball"); } //发糖 public void dispense(){ System.out.println("YOU'RE A WINNER! You get two gumballs for your quater") gumballMachine.releaseBall(); if(gumballMachine.getCount()==0){ gumballMachine.setState(gumballMachine.SoldOutState()); }else{ gumballMachine.releaseBall(); if(gumballMachine.getCount()>0){ gumballMachine.setState(gumballMachine.getNoQuarterState()); }else{ System.out.println("Oops,out of gumball"); gumballMachine.setState(gumballMachine.getSoldOutState()); } } }}//糖果售罄状态public class SoldOutState implements State{ GumballMachine gumballMachine; //状态被实例化是,传入GumballMachine的引用作为参数 public SoldOutState(GumballMachine gumballMachine){ this.gumballMachine=gumballMachine; } //在糖果售罄的状态下,除非重新填充糖果机,否则不做任何事 public void insertQuater(){ System.out.println("You can't insert a quarter,the machine is sold out"); } public void ejectQuarter(){ System.out.println("You can't eject,you haven't inserted a quarter yet"); } public void turnCrank(){ System.out.println("You turned,but there are no gumballs"); } public void dispense(){ System.out.println("No gumball dispensed"); }}public 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; //若糖果数>0,则将状态设为noQuarterState if(numberGumballs>0){ state=noQuarterState; } } //设置动作,并因动作改变相应的状态 public void insertQuarter(){ state.insertQuarter(); } public void ejectQuarter(){ state.ejectQuarter(); } /*不需要在GumballMachine中准备一个dispense()的动作方法,因为这是一个内部动作; 用户不可以直接要求一个机器发放糖果。但可以在状态对象的turnCrank()方法中调用dispense()方法*/ public void turnCrank(){ state.turnCrank(); state.dispense(); } //允许其他对象将机器的状态转换到不同的状态 void setState(State state){ this.state=state; } //提供一个releaseBall()的辅助方法来释放糖果,并将count值减1 void releaseBall(){ System.out.println("A gumball comes rolling out the slot..."); if(count!=0){ count=count-1; } } //更新糖果机内的糖果数目,并重置机器的状态 void refill(int count){ this.count=count; state=noQuarterState; } /*其他方法,包括像getNoQuarterState()这样的用来获得每个对象的方法, 还包括可以取得糖果数目的getCount()方法*/}//演示public class GumballMachineTestDriver{ public static void main(String[] args){ GumballMachine gumballMachine= new GumballMachine(5);//糖果机装5颗糖 System.out.println(gumballMachine); gumballMachine.insertQuarter(); gumballMachine.turnCrank(); System.out.println(gumballMachine); gumballMachine.insertQuarter(); gumballMachine.turnCrank(); gumballMachine.insertQuarter(); gumballMachine.turnCrank(); System.out.println(gumballMachine); }}
区分模式
状态模式:封装基于状态的行为,并将行为委托到当前状态
策略模式:将可以互换的行为封装起来。然后使用委托的方法,觉得使用哪一个行为
模板方法模式:由子类决定如何实现算法中的某些步骤
要点
(1)状态模式允许一个对象基于内部状态而拥有不同的行为。
(2)和程序状态机(PSM)不同,状态模式用类来表示状态。
(3)Context会将行为委托给当前状态对象。
(4)通过将每一个状态封装进一个类,我们把以后需要做的任何改变局部化了。
(5)状态模式和策略模式有相同的类图,但是他们的意图不同。
(6)策略模式通常会用行为或算法配置Context类。
(7)状态模式允许Context随着状态的改变而改变行为。
(8)状态转换可以有State类或Context类控制。
(9)使用状态模式通常会导致设计中类的数目大量增加。
(10)状态栏可以被多个Context实例共享。
0 0
- HeadFirst 设计模式 10状态模式(糖果机)
- 《HeadFirst设计模式》Delphi7代码---状态模式
- Delphi 设计模式:《HeadFirst设计模式》Delphi7代码---状态模式
- 《HeadFirst设计模式》书摘-状态模式/代理模式
- 设计模式(Headfirst)学习
- headfirst/状态模式笔记
- HeadFirst 设计模式学习笔记11——状态模式
- HeadFirst设计模式学习笔记7-状态模式
- 【HeadFirst 设计模式学习笔记】11 状态模式
- HeadFirst设计模式_读书笔记_010_状态模式
- 【HeadFirst设计模式】(一)策略模式
- 【HeadFirst设计模式】(二)观察者模式
- HeadFirst设计模式(策略模式Strategy)
- HeadFirst设计模式
- HeadFirst -------- 设计模式要点
- Headfirst设计模式 整理
- HeadFirst 设计模式 总
- HeadFirst设计模式
- Arcengine获取图层某个字段唯一值的方法
- 后勤报修项目心得
- 九度oj 1068
- 并发
- (C/C++ 学习笔记)函数指针语法基础
- HeadFirst 设计模式 10状态模式(糖果机)
- js对话框
- java中的数组的常见操作问题
- UIWebView与JS的深度交互
- MyEclipse 快捷键大全
- 2015 ACM多校训练第二场
- Android开发性能优化大总结
- HeadFirst 设计模式 11代理模式
- Mac下Android Studio快捷键