HeadFrist设计模式学习之状态模式
2016-06-16 10:31
375 查看
HeadFrist设计模式学习之状态模式
状态模式定义状态模式允许对象在内部改变状态时改变它的行为,对象看起来好像修改了它的类。
状态模式用于当类由于条件语句而使逻辑变得十分复杂并且难于修改时,它将逻辑根据条件分成不同的类(每个类称之为一个状态),从而使类的内部结构变得清晰易读并且更符合业务逻辑。
需求——实现下列糖果机
class gumballMachine { int Money = 10; // 糖果机用于找零的钱 int price = 1; // 糖果的单价 private int change=0;// 找零金额 public void soldGumball() { } public void toGiveChange() { } public void on() { } public void off() { } public void putMoneyIn(int moeny) { } }
上述代码是一个糖果机,具有方法:开 关 找零 放入钱 出售糖果 5 个方法,如果用普通的实现方法,
例如在soldGumball()方法中,需要判断糖果机是否开机,放入的钱是否足够,是否能够找零。。。。最糟糕的是,如果加入新的方法,比如抽取随机用户得到双倍的糖,所有的方法就都得做出修改!
加入状态模式的糖果机
首先改造糖果机:
class gumballMachine { private int Money = 10; // 糖果机用于找零的钱 private int price = 1; // 糖果的单价 private int change = 0;//找零金额 toGiveChangeState togivechangestate; offState offstate; onState onstate; State state = new onState(this); soldGumballState soldgumballstate; public gumballMachine() { // TODO Auto-generated constructor stub this.offstate = new offState(this); this.onstate = new onState(this); this.togivechangestate = new toGiveChangeState(this); this.soldgumballstate = new soldGumballState(this); } public void soldGumball() { state.soldGumball(); } public void toGiveChange() { state.toGiveChange(); } public void on() { state.on(); } public void off() { state.off(); } public void putMoneyIn(int money) { state.putMoneyIn(money); } //改变状态 public void toState(State state) { this.state = state; } //下面都是get/set方法 public int getChange() { return change; } public void setChange(int change) { this.change = change; } public soldGumballState getSoldgumballstate() { return soldgumballstate; } public void setSoldgumballstate(soldGumballState soldgumballstate) { this.soldgumballstate = soldgumballstate; } public int getMoney() { return Money; } public void setMoney(int money) { Money = money; } public int getPrice() { return price; } public void setPrice(int price) { this.price = price; } public toGiveChangeState getTogivechangestate() { return togivechangestate; } public void setTogivechangestate(toGiveChangeState togivechangestate) { this.togivechangestate = togivechangestate; } public offState getOffstate() { return offstate; } public void setOffstate(offState offstate) { this.offstate = offstate; } public onState getOnstate() { return onstate; } public void setOnstate(onState onstate) { this.onstate = onstate; } }
写出state接口
interface State { public void soldGumball(); public void toGiveChange(); public void on(); public void off(); public void putMoneyIn(int money); }
糖果机默认状态是开启,所以先看onState
class onState implements State { private gumballMachine gm; public onState(gumballMachine gm) { // TODO Auto-generated constructor stub this.gm=gm; } @Override public void soldGumball() { // TODO Auto-generated method stub System.out.println("请先投入钱币--soldGumball"); } @Override public void toGiveChange() { // TODO Auto-generated method stub System.out.println("请先投入钱币--toGiveChange"); } @Override public void on() { // TODO Auto-generated method stub System.out.println("机器已经打开--on"); } @Override public void off() { // TODO Auto-generated method stub gm.toState(gm.getOffstate()); } @Override public void putMoneyIn(int money) { // TODO Auto-generated method stub if(money>gm.getPrice()&&(money-gm.getPrice()<=gm.getMoney()))//如果投入的钱大于单价并且可以找零,则进入找零状态 { gm.setChange(money-gm.getPrice()); gm.setMoney(gm.getMoney()+money);; gm.toState(gm.getTogivechangestate());//状态转换 } else System.out.println("Money return "+money); } }
在onstate中,可用的方法是putMoneyIn和off,所以在这两个方法里做出了有意义的实现,其他均为提示,在putMoneyIn()方法中,用了一个if语句,这不是一个好的实现,因为状态模式就是为了消除if带来的复杂性,所以,一旦在状态模式中出现if,那么可能意味着,代码是有瑕疵的。
下面贴出剩余状态的代码
offstate
class offState implements State { private gumballMachine gm; public offState(gumballMachine gm) { // TODO Auto-generated constructor stub this.gm=gm; } @Override public void soldGumball() { // TODO Auto-generated method stub System.out.println("机器没有打开--soldGumball"); } @Ove 4000 rride public void toGiveChange() { // TODO Auto-generated method stub System.out.println("机器没有打开--toGiveChange"); } @Override public void on() { // TODO Auto-generated method stub gm.toState(gm.getOnstate()); } @Override public void off() { // TODO Auto-generated method stub System.out.println("................"); } @Override public void putMoneyIn(int money) { // TODO Auto-generated method stub System.out.println("机器没有打开--putMoneyIn"); } }
toGiveChangeState
class toGiveChangeState implements State { private gumballMachine gm; public toGiveChangeState(gumballMachine gm) { // TODO Auto-generated constructor stub this.gm=gm; } @Override public void soldGumball() { // TODO Auto-generated method stub } @Override public void toGiveChange() { // TODO Auto-generated method stub System.out.println("GiveChange————"+gm.getChange()); gm.setMoney(gm.getMoney()-gm.getChange()); gm.setChange(0); gm.toState(gm.getSoldgumballstate()); } @Override public void on() { // TODO Auto-generated method stub System.out.println("机器已经开启--on"); } @Override public void off() { // TODO Auto-generated method stub System.out.println("操作进行中,请勿关闭--off"); } @Override public void putMoneyIn(int money) { // TODO Auto-generated method stub System.out.println("您已经投币--putMoneyIn"); } } **soldGumballState ** class soldGumballState implements State { private gumballMachine gm; public soldGumballState(gumballMachine gm) { // TODO Auto-generated constructor stub this.gm=gm; } @Override public void soldGumball() { // TODO Auto-generated method stub System.out.println("one Gumball!!!!!!"); gm.toState(gm.getOnstate()); } @Override public void toGiveChange() { // TODO Auto-generated method stub System.out.println("已经找零"); } @Override public void on() { // TODO Auto-generated method stub System.out.println("已开机"); } @Override public void off() { // TODO Auto-generated method stub System.out.println("正在操作。。。。"); } @Override public void putMoneyIn(int money) { // TODO Auto-generated method stub System.out.println("已经投币,谢谢"); } }
测试代码
public static void main(String[] args) { // TODO Auto-generated method stub gumballMachine gm=new gumballMachine(); gm.putMoneyIn(8); gm.toGiveChange(); gm.soldGumball(); }
结果
GiveChange————7 one Gumball!!!!!!
在来看看应对错误操作
public static void main(String[] args) { // TODO Auto-generated method stub gumballMachine gm=new gumballMachine(); gm.putMoneyIn(8); gm.putMoneyIn(8);//二次投币 gm.off();//操作过程中关机 gm.toGiveChange(); gm.off();//操作过程中关机 gm.on();//操作过程中开机 gm.soldGumball(); gm.off();//正常关机 gm.putMoneyIn(8);//关机状态下投币 }
上述代码在第一次测试的代码中加入了一些正常或错误的操作,下面看结果
您已经投币--putMoneyIn 操作进行中,请勿关闭--off GiveChange————7 正在操作。。。。 已开机 one Gumball!!!!!! 机器没有打开--putMoneyIn
机器的运行可以看出是正常的。
如果单纯的只考虑如何实现这个糖果机的话,远远不需要这么多的代码——200+行,但是这样写出的代码过于复杂并且难以读懂,尤其是在变更需求之后,代码更加难以维护,但是状态模式解决了这些问题,状态模式把逻辑的转换放到类的结构上,这样能使逻辑变得容易理解(几乎是业务逻辑的映射),变更需求虽然需要更多的代码,但是这是值得的,因为代码虽然多但是不会复杂,逻辑不会变得混乱。
相关文章推荐
- PropertyChangeListener简单理解
- 什么是设计模式
- 设计模式之创建型模式 - 特别的变量问题
- 七、设计模式——装饰模式
- 设计模式总结
- 设计模式之创建型模式
- 浅谈设计模式的学习
- Ruby设计模式编程之适配器模式实战攻略
- 实例讲解Ruby使用设计模式中的装饰器模式的方法
- 设计模式中的模板方法模式在Ruby中的应用实例两则
- Ruby设计模式编程中对外观模式的应用实例分析
- 实例解析Ruby设计模式编程中Strategy策略模式的使用
- Ruby中使用设计模式中的简单工厂模式和工厂方法模式
- Ruby使用设计模式中的代理模式与装饰模式的代码实例
- 详解组合模式的结构及其在Ruby设计模式编程中的运用
- C# 设计模式系列教程-建造者模式
- C#编程中使用设计模式中的原型模式的实例讲解
- 使用设计模式中的工厂方法模式进行C#编程的示例讲解
- 实例解析C#设计模式编程中简单工厂模式的使用
- 详解C#设计模式编程中生成器模式的使用