当前位置: 首页 > news >正文

《HeadFirst设计模式(第二版)》第十章代码——状态模式

         如下图所示,这是一个糖果机的状态机图,要求使用代码实现:

 初始版本:
package Chapter10_StatePattern.Origin;/*** @Author 竹心* @Date 2023/8/19**/public class GumballMachine {final static int SOLD_OUT = 0;final static int NO_QUARTER = 1;final static int HAS_QUARTER = 2;final static int SOLD = 3;int state = SOLD_OUT;int count = 0;public GumballMachine(int count) {this.count = count;if (count > 0) {state = NO_QUARTER;}}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 inserted 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");}}public void ejectQuarter() {if (state == HAS_QUARTER) {System.out.println("Quarter returned");state = NO_QUARTER;} else if (state == NO_QUARTER) {System.out.println("You haven't inserted a quarter");} else if (state == SOLD) {System.out.println("Sorry, you already turned the crank");} else if (state == SOLD_OUT) {System.out.println("You can't eject, you haven't inserted a quarter yet");}}public void turnCrank() {if (state == SOLD) {System.out.println("Turning twice doesn't get you another gumball!");} else if (state == NO_QUARTER) {System.out.println("You turned but there's no quarter");} else if (state == SOLD_OUT) {System.out.println("You turned, but there are no gumballs");} else if (state == HAS_QUARTER) {System.out.println("You turned...");state = SOLD;dispense();}}private void dispense() {if (state == SOLD) {System.out.println("A gumball comes rolling out the slot");count = count - 1;if (count == 0) {System.out.println("Oops, out of gumballs!");state = SOLD_OUT;} else {state = NO_QUARTER;}} else if (state == NO_QUARTER) {System.out.println("You need to pay first");} else if (state == SOLD_OUT) {System.out.println("No gumball dispensed");} else if (state == HAS_QUARTER) {System.out.println("No gumball dispensed");}}public void refill(int numGumBalls) {this.count = numGumBalls;state = NO_QUARTER;}public String toString() {StringBuffer result = new StringBuffer();result.append("\nMighty Gumball, Inc.");result.append("\nJava-enabled Standing Gumball Model #2004\n");result.append("Inventory: " + count + " gumball");if (count != 1) {result.append("s");}result.append("\nMachine is ");if (state == SOLD_OUT) {result.append("sold out");} else if (state == NO_QUARTER) {result.append("waiting for quarter");} else if (state == HAS_QUARTER) {result.append("waiting for turn of crank");} else if (state == SOLD) {result.append("delivering a gumball");}result.append("\n");return result.toString();}
}

        上面的代码很明显极其不利于本维护:比如要添加一个新的状态--每次投入25分钱都能有十分之一的概率获得两个糖果。

        很明显上面的代码又要添加一堆if-else了,这种情况下就可以使用状态模式:

状态模式:

        允许对象内部状态改变时改变其行为。对象看起来好像改变了他的类。

使用了状态模式之后的类图:

 State
package Chapter10_StatePattern.State;/*** @Author 竹心* @Date 2023/8/19**/public interface State {public void insertQuarter();//投入25分public void ejectQuarter();//吐出25分钱public void turnCrank();//摇动摇杆public void dispense();//发放public void refill();//填充糖果
}

接下来是五个状态类

NoQuarterState
package Chapter10_StatePattern.State;/*** @Author 竹心* @Date 2023/8/19**///没有25美分
public 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.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 void refill() { }public String toString() {return "waiting for quarter";}
}
 HasQuarterState
package Chapter10_StatePattern.State;import java.util.Random;/*** @Author 竹心* @Date 2023/8/19**///有25美分
public 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.getNoQuarterState());}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 void refill() { }public String toString() {return "waiting for turn of crank";}
}
SoldState
package Chapter10_StatePattern.State;/*** @Author 竹心* @Date 2023/8/19**/
//糖果已售出
public class SoldState implements State{GumballMachine gumballMachine;public SoldState(GumballMachine gumballMachine) {this.gumballMachine = gumballMachine;}public void insertQuarter() {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 gumballs!");gumballMachine.setState(gumballMachine.getSoldOutState());}}public void refill() { }public String toString() {return "dispensing a gumball";}
}
SoldOutState
package Chapter10_StatePattern.State;/*** @Author 竹心* @Date 2023/8/19**///糖果已售罄
public class SoldOutState implements State{GumballMachine gumballMachine;public SoldOutState(GumballMachine gumballMachine) {this.gumballMachine = gumballMachine;}public void insertQuarter() {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 void refill() {gumballMachine.setState(gumballMachine.getNoQuarterState());}public String toString() {return "sold out";}
}
WinnerState
package Chapter10_StatePattern.State;/*** @Author 竹心* @Date 2023/8/19**///获得两个糖果
public class WinnerState implements State{GumballMachine gumballMachine;public WinnerState(GumballMachine gumballMachine) {this.gumballMachine = gumballMachine;}public void insertQuarter() {System.out.println("Please wait, we're already giving you a Gumball");}public void ejectQuarter() {System.out.println("Please wait, we're already giving you a Gumball");}public void turnCrank() {System.out.println("Turning again doesn't get you another gumball!");}public void dispense() {gumballMachine.releaseBall();if (gumballMachine.getCount() == 0) {gumballMachine.setState(gumballMachine.getSoldOutState());} else {gumballMachine.releaseBall();System.out.println("YOU'RE A WINNER! You got two gumballs for your quarter");if (gumballMachine.getCount() > 0) {gumballMachine.setState(gumballMachine.getNoQuarterState());} else {System.out.println("Oops, out of gumballs!");gumballMachine.setState(gumballMachine.getSoldOutState());}}}public void refill() { }public String toString() {return "dispensing two gumballs for your quarter, because YOU'RE A WINNER!";}}
GumballMachine:
package Chapter10_StatePattern.State;/*** @Author 竹心* @Date 2023/8/19**/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;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;}}int getCount() {return count;}void refill(int count) {this.count += count;System.out.println("The gumball machine was just refilled; its new count is: " + this.count);state.refill();}public State getState() {return state;}public State getSoldOutState() {return soldOutState;}public State getNoQuarterState() {return noQuarterState;}public State getHasQuarterState() {return hasQuarterState;}public State getSoldState() {return soldState;}public State getWinnerState() {return winnerState;}public String toString() {StringBuffer result = new StringBuffer();result.append("\nMighty Gumball, Inc.");result.append("\nJava-enabled Standing Gumball Model #2004");result.append("\nInventory: " + count + " gumball");if (count != 1) {result.append("s");}result.append("\n");result.append("Machine is " + state + "\n");return result.toString();}
}
GumballMachineTestDrive
package Chapter10_StatePattern.State;import Chapter10_StatePattern.Origin.GumballMachine;/*** @Author 竹心* @Date 2023/8/19**/public class GumballMachineTestDrive {public static void main(String[] args) {GumballMachine gumballMachine =new GumballMachine(10);System.out.println(gumballMachine);gumballMachine.insertQuarter();gumballMachine.turnCrank();gumballMachine.insertQuarter();gumballMachine.turnCrank();System.out.println(gumballMachine);gumballMachine.insertQuarter();gumballMachine.turnCrank();gumballMachine.insertQuarter();gumballMachine.turnCrank();System.out.println(gumballMachine);gumballMachine.insertQuarter();gumballMachine.turnCrank();gumballMachine.insertQuarter();gumballMachine.turnCrank();System.out.println(gumballMachine);gumballMachine.insertQuarter();gumballMachine.turnCrank();gumballMachine.insertQuarter();gumballMachine.turnCrank();System.out.println(gumballMachine);gumballMachine.insertQuarter();gumballMachine.turnCrank();gumballMachine.insertQuarter();gumballMachine.turnCrank();System.out.println(gumballMachine);}
}

http://www.lryc.cn/news/132324.html

相关文章:

  • day-25 代码随想录算法训练营(19)回溯part02
  • PG逻辑备份与恢复
  • 图数据库_Neo4j和SpringBoot整合使用_实战创建明星关系图谱---Neo4j图数据库工作笔记0010
  • Linux网络编程:Socket套接字编程(Server服务器 Client客户端)
  • Mac OS下应用Python+Selenium实现web自动化测试
  • 每天一道leetcode:934. 最短的桥(图论中等广度优先遍历)
  • 【学习日记】【FreeRTOS】FreeRTOS 移植到 STM32F103C8
  • Qt 屏幕偶发性失灵
  • 如何在pycharm中指定GPU
  • C#判断字符串中有没有字母,正则表达式、IsLetter
  • Jtti:Ubuntu怎么限制指定端口和IP访问
  • 机器学习/深度学习需要掌握的linux基础命令
  • C++11 std::async推荐使用 std::launch::async 模式
  • 没有使用springboot 单独使用spring-boot-starter-logging
  • 创建Azure资源锁
  • 卷积神经网络教程 (CNN) – 使用 TensorFlow 在 Python 中开发图像分类器
  • MyBatis XML映射处理CLOB和BLOB类型
  • FPGA_学习_14_第一个自写模块的感悟和ila在线调试教程与技巧(寻找APD的击穿偏压)
  • 【2023新教程】树莓派定时自动拍照并上传腾讯云对象存储COS
  • 校企合作谋发展 合作共赢谱新篇|云畅科技与湖南民族职业学院签订校企合作协议
  • vue技术学习
  • 基于空间的图卷积神经网络:GNN
  • .net core发布到IIS上出现 HTTP 错误 500.19
  • 01_Redis单线程与多线程
  • 机器学习——随机森林【手动代码】
  • Vue 2 处理边界情况
  • 写一个mysql 正则表达式,每三个img标签图片后面添加<hr>
  • Spring MVC异常处理
  • Centos7安装docker后默认开启docker0的网卡|卸载默认网卡
  • 04_Redis与mysql数据双写一致性案例