状态模式(State Pattern)是一种行为型设计模式,它允许对象在其内部状态发生改变时改变它的行为。在状态模式中,对象会将自己的状态委托给不同的状态类,从而实现不同状态下的不同行为。
下面是一个简单的例子,假设我们正在编写一个自动售货机程序,当售货机处于不同的状态时,它的行为将有所不同。例如,当售货机处于“等待投币”状态时,如果用户投入硬币,则售货机会显示商品的价格,等待用户继续操作。如果售货机处于“出售商品”状态时,售货机会发出嘟嘟声并释放商品,等待用户取走商品。我们可以使用状态模式来实现这个功能。
首先,我们需要定义一个状态接口,它包含了在不同状态下售货机的行为:
// 状态接口
public interface VendingMachineState {
void insertCoin();
void dispenseItem();
}
然后,我们需要为每个状态实现这个接口:
// 等待投币状态
public class WaitingCoinState implements VendingMachineState {
@Override
public void insertCoin() {
System.out.println("硬币已插入。");
}
@Override
public void dispenseItem() {
System.out.println("请先投币。");
}
}
// 出售商品状态
public class DispensingState implements VendingMachineState {
@Override
public void insertCoin() {
System.out.println("请稍等,正在出售商品。");
}
@Override
public void dispenseItem() {
System.out.println("出售商品。");
}
}
接下来,我们需要实现售货机类,并在其中维护当前状态:
public class VendingMachine {
// 状态枚举
private final static int WAITING_COIN_STATE = 0;
private final static int DISPENSING_STATE = 1;
// 当前状态
private int currentState;
// 不同状态对应的实例
private VendingMachineState waitingCoinState;
private VendingMachineState dispensingState;
public VendingMachine() {
// 初始化状态
currentState = WAITING_COIN_STATE;
waitingCoinState = new WaitingCoinState();
dispensingState = new DispensingState();
}
public void insertCoin() {
if (currentState == WAITING_COIN_STATE) {
waitingCoinState.insertCoin();
currentState = DISPENSING_STATE;
} else if (currentState == DISPENSING_STATE) {
dispensingState.insertCoin();
}
}
public void dispenseItem() {
if (currentState == WAITING_COIN_STATE) {
waitingCoinState.dispenseItem();
} else if (currentState == DISPENSING_STATE) {
dispensingState.dispenseItem();
currentState = WAITING_COIN_STATE;
}
}
}
最后,我们可以在客户端代码中使用售货机类来模拟售货机的使用:
public class Client {
public static void main(String[] args) {
VendingMachine vendingMachine = new VendingMachine();
vendingMachine.insertCoin(); // 输出:硬币已插入。
vendingMachine.dispenseItem(); // 输出:请先投币。
vendingMachine.insertCoin(); // 输出:硬币已插入。
vendingMachine.dispenseItem(); // 输出:出售商品。
vendingMachine.insertCoin(); // 输出:请稍等,正在出售商品。
vendingMachine.insertCoin(); // 输出:请稍等,正在出售商品。
vendingMachine.dispenseItem(); // 输出:出售商品。
vendingMachine.dispenseItem(); // 输出:请先投币。
}
}
在这个例子中,我们使用状态模式来实现了一个自动售货机。当售货机处于等待投币状态时,如果用户投入硬币,则售货机会将状态切换为出售商品状态,并输出“硬币已插入”。如果售货机处于出售商品状态时,售货机会发出“请稍等,正在出售商品”的提示,并等待用户取走商品。如果用户再次投入硬币,则售货机会输出“请稍等,正在出售商品”提示,表示当前正在出售商品。如果用户取走商品,则售货机会将状态切换为等待投币状态,并输出“出售商品”。如果用户在等待投币状态下直接请求出售商品,则售货机会输出“请先投币”的提示。
总之,状态模式通过将对象的状态委托给不同的状态类来实现不同状态下的不同行为,使得代码更加可维护和易于扩展。