经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » 设计模式 » 查看文章
设计模式之状态模式(二)
来源:cnblogs  作者:小酒窝  时间:2019/8/29 8:50:46  对本文有异议

在上一次的文章里,我们看到,需求的变更,迫使我们需要重新改造现有的糖果机代码来符合这个新提的需求。但是,也并没有难倒我们,至少我们在文末给出了思路和类图,不知道你想的怎么样了呢。

我们不来虚的,直接进入正题,开启我们的学习之旅。

实现我们的状态类

现在是实现一个状态的时候了:我们知道我们要的行为是什么,我们只需要把它变成代码。我们打算完全遵守所写下的状态机代码,但是这一次是分散在不同的类中。比如我们以NoQuarterState类为例。

  1. public class NoQuarterState implements State {
  2. GumballMachine gumballMachine;
  3. public NoQuarterState(GumballMachine gumballMachine) {
  4. this.gumballMachine = gumballMachine;
  5. }
  6. public void insertQuarter() {
  7. System.out.println("You inserted a quarter");
  8. gumballMachine.setState(gumballMachine.getHasQuarterState());
  9. }
  10. public void ejectQuarter() {
  11. System.out.println("You haven't inserted a quarter");
  12. }
  13. public void turnCrank() {
  14. System.out.println("You turned, but there's no quarter");
  15. }
  16. public void dispense() {
  17. System.out.println("You need to pay first");
  18. }
  19. }

在完成这些状态类之前,我们需要重新改造糖果机,好让你了解这一切的原理。我们把原来使用整数代表的状态改为状态对象:

  1. State soldOutState;
  2. State noQuarterState;
  3. State hasQuarterState;
  4. State soldState;
  5. State state;
  6. int count = 0;

这样,我们就有了一个完整的糖果机类

  1. public class GumballMachine {
  2. State soldOutState;
  3. State noQuarterState;
  4. State hasQuarterState;
  5. State soldState;
  6. State state;
  7. int count = 0;
  8. public GumballMachine(int numberGumballs) {
  9. soldOutState = new SoldOutState(this);
  10. noQuarterState = new NoQuarterState(this);
  11. hasQuarterState = new HasQuarterState(this);
  12. soldState = new SoldState(this);
  13. this.count = numberGumballs;
  14. if (numberGumballs > 0) {
  15. state = noQuarterState;
  16. } else {
  17. state = soldOutState;
  18. }
  19. }
  20. public void insertQuarter() {
  21. state.insertQuarter();
  22. }
  23. public void ejectQuarter() {
  24. state.ejectQuarter();
  25. }
  26. public void turnCrank() {
  27. state.turnCrank();
  28. state.dispense();
  29. }
  30. void releaseBall() {
  31. System.out.println("A gumball comes rolling out the slot...");
  32. if (count != 0) {
  33. count = count - 1;
  34. }
  35. }
  36. // 后面部分省略
  37. }

好了,这样子,我们就能继续实现更多的状态类了。比如我们能实现HasQuarterState和SoldState类

  1. public class HasQuarterState implements State {
  2. GumballMachine gumballMachine;
  3. public HasQuarterState(GumballMachine gumballMachine) {
  4. this.gumballMachine = gumballMachine;
  5. }
  6. public void insertQuarter() {
  7. System.out.println("You can't insert another quarter");
  8. }
  9. public void ejectQuarter() {
  10. System.out.println("Quarter returned");
  11. gumballMachine.setState(gumballMachine.getNoQuarterState());
  12. }
  13. public void turnCrank() {
  14. System.out.println("You turned...");
  15. gumballMachine.setState(gumballMachine.getSoldState());
  16. }
  17. public void dispense() {
  18. System.out.println("No gumball dispensed");
  19. }
  20. }
  1. public class SoldState implements State {
  2. GumballMachine gumballMachine;
  3. public SoldState(GumballMachine gumballMachine) {
  4. this.gumballMachine = gumballMachine;
  5. }
  6. public void insertQuarter() {
  7. System.out.println("Please wait, we're already giving you a gumball");
  8. }
  9. public void ejectQuarter() {
  10. System.out.println("Sorry, you already turned the crank");
  11. }
  12. public void turnCrank() {
  13. System.out.println("Turning twice doesn't get you another gumball!");
  14. }
  15. public void dispense() {
  16. gumballMachine.releaseBall();
  17. if (gumballMachine.getCount() > 0) {
  18. gumballMachine.setState(gumballMachine.getNoQuarterState());
  19. } else {
  20. System.out.println("Oops, out of gumballs!");
  21. gumballMachine.setState(gumballMachine.getSoldOutState());
  22. }
  23. }
  24. }

检查一下,到目前为止我们做了啥

你现在有了一个糖果机的实现,他在结构上和前一个版本差异很大,但是功能上却是一样的。我们发现,你已经实现了以下几点:

  • 将每个状态的行为局部化到它自己的类中

  • 将容易产生问题的if语句删除,以方便日后的维护

  • 让每个状态“对修改关闭”,让糖果机“对扩展开放”,因为可以加入新的状态类

  • 创建一个新的代码基和类结构,这更能映射万能糖果公司的图,而且更容易阅读和理解

定义状态模式

是的,就在刚才,我们已经实现了状态模式。现在让我们来看看什么是状态模式。

状态模式允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。

让我们好好看下状态模式的类图:

这个类图和策略模式的类图是一样的。但是虽然类图是一样的,但是两个模式的差别在于它们的“意图”不同。状态模式将一群行为封装在状态对象中,context行为随时可委托到那些状态对象中的一个。对于策略模式而言,客户通常主动指定context所要组合的策略对象是哪一个。

等等等等,之前不是说有十次抽中一次的游戏吗?怎么还没写出来呢?哈哈哈哈,不急不急,以上内容你都消化了吗?如果你消化的话,请你耐心等待,倘若没有,那请你先好好学习这些吧。我将在下次把抽奖这个搞定。

拜拜!

「奔跑吧攻城狮」感谢大家的关注,现在后台回复「设计模式」赠你小编精心挑选设计模式书籍。小编最近开窍,组建了一个技术交流群,回复「加群」即可解锁。

原文链接:http://www.cnblogs.com/dimple91/p/11423339.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号