让我们通过一个生活中的例子来深入理解状态模式:咖啡机的工作流程。想象一下,一个咖啡机有几种状态:无币状态、有币状态、制作咖啡状态和咖啡制作完成·状态。用户在每个状态下与咖啡机的互动都是不同的。
状态模式在咖啡机中的应用
- 无币状态:用户可以投币,咖啡机随后进入有币状态。
- 有币状态:用户可以选择退币,回到无币状态,或者按下制作按钮,咖啡机进入制作咖啡状态。
- 制作咖啡状态:咖啡机开始制作咖啡,完成后进入咖啡制作完成状态。
- 咖啡制作完成状态:用户取走咖啡,咖啡机回到无币状态。
示例代码
首先,定义咖啡机的状态接口:
java
interface CoffeeMachineState {
void insertCoin();
void pressButton();
void takeCoffee();
void refundCoin();
}
然后,实现各个状态:
java
// 无币状态
class NoCoinState implements CoffeeMachineState {
private CoffeeMachine machine;
public NoCoinState(CoffeeMachine machine) {
this.machine = machine;
}
public void insertCoin() {
System.out.println("投币成功");
machine.setState(machine.getHasCoinState());
}
public void pressButton() {
System.out.println("请先投币");
}
public void takeCoffee() {
System.out.println("请先投币");
}
public void refundCoin() {
System.out.println("您还没有投币");
}
}
// 有币状态
class HasCoinState implements CoffeeMachineState {
private CoffeeMachine machine;
public HasCoinState(CoffeeMachine machine) {
this.machine = machine;
}
public void insertCoin() {
System.out.println("您已经投过币了");
}
public void pressButton() {
System.out.println("咖啡制作中");
machine.setState(machine.getCoffeeMakingState());
}
public void takeCoffee() {
System.out.println("咖啡还未制作完成");
}
public void refundCoin() {
System.out.println("退币成功");
machine.setState(machine.getNoCoinState());
}
}
// 添加制作咖啡状态和咖啡制作完成状态代码...
接下来,实现咖啡机上下文:
java
class CoffeeMachine {
private CoffeeMachineState noCoinState;
private CoffeeMachineState hasCoinState;
private CoffeeMachineState coffeeMakingState;
private CoffeeMachineState coffeeReadyState;
private CoffeeMachineState currentState;
public CoffeeMachine() {
noCoinState = new NoCoinState(this);
hasCoinState = new HasCoinState(this);
coffeeMakingState = new CoffeeMakingState(this);
coffeeReadyState = new CoffeeReadyState(this);
currentState = noCoinState; // 初始状态为无币状态
}
public void setState(CoffeeMachineState state) {
this.currentState = state;
}
public void insertCoin() {
currentState.insertCoin();
}
public void pressButton() {
currentState.pressButton();
}
public void takeCoffee() {
currentState.takeCoffee();
}
public void refundCoin() {
currentState.refundCoin();
}
// 省略getter方法...
}
通过上述代码,我们可以看到状态模式如何在咖啡机中被应用。状态模式使得咖啡机的状态转换逻辑变得清晰,每个状态的行为封装在各自的类中,易于理解和扩展。
总结
状态模式通过将状态的变化逻辑分散到不同的状态对象中,而非集中在一个大的条件语句里,使得代码更加模块化,易于理解和维护。这种模式非常适用于对象的行为依赖于其状态的场景,如咖啡机示例所示,它帮助我们清晰地模拟和管理了咖啡机在不同状态下的行为。