状态模式学习笔记
简介
状态模式(State Pattern)是一种行为型设计模式,它允许对象在内部状态改变时更改其行为。这种模式通过将对象状态转移的责任分配给代表状态的对象来实现。
实例
假设我们正在设计一个自动售货机系统。该系统中的自动售货机有三种状态:待机状态、选购商品状态和支付状态。在待机状态下,自动售货机不允许用户选购商品。在选购商品状态下,自动售货机会显示商品列表,并等待用户选择要购买的商品。在支付状态下,自动售货机会显示所选商品的价格,并等待用户支付。
我们可以使用状态模式来实现该系统。首先,我们定义一个接口 VendingMachineState
表示自动售货机的状态:
javaCopy Codepublic interface VendingMachineState {
void selectItem(String item);
void insertMoney(int amount);
void dispense();
}
然后,我们定义三个具体状态类:IdleState
(待机状态)、SelectItemState
(选购商品状态)和 PaymentState
(支付状态)。
javaCopy Codepublic class IdleState implements VendingMachineState {
@Override
public void selectItem(String item) {
// 不允许选择商品
System.out.println("Please insert money first.");
}
@Override
public void insertMoney(int amount) {
// 进入选购商品状态
System.out.println(amount + " yuan inserted.");
vendingMachine.setState(new SelectItemState(vendingMachine));
}
@Override
public void dispense() {
// 不允许发放商品
System.out.println("Please select item first.");
}
}
public class SelectItemState implements VendingMachineState {
@Override
public void selectItem(String item) {
// 选择商品后进入支付状态
System.out.println(item + " selected.");
vendingMachine.setItem(item);
vendingMachine.setState(new PaymentState(vendingMachine));
}
@Override
public void insertMoney(int amount) {
// 已经在选购商品状态下,不需要再次插入钱币
System.out.println("You have already inserted money.");
}
@Override
public void dispense() {
// 不允许发放商品
System.out.println("Please pay first.");
}
}
public class PaymentState implements VendingMachineState {
@Override
public void selectItem(String item) {
// 已经在支付状态下,不允许更改选择的商品
System.out.println("You have already selected item: " + vendingMachine.getItem());
}
@Override
public void insertMoney(int amount) {
int total = vendingMachine.getAmount() + amount;
vendingMachine.setAmount(total);
// 判断是否已经足够支付
if (total >= vendingMachine.getPrice()) {
vendingMachine.setState(new DispensingState(vendingMachine));
} else {
System.out.println("Current balance: " + total);
}
}
@Override
public void dispense() {
// 不允许发放商品
System.out.println("Please insert enough money.");
}
}
public class DispensingState implements VendingMachineState {
@Override
public void selectItem(String item) {
// 已经在发放商品状态下,不允许更改选择的商品
System.out.println("You have already selected item: " + vendingMachine.getItem());
}
@Override
public void insertMoney(int amount) {
// 已经足够支付,不需要继续插入钱币
System.out.println("You have already inserted enough money.");
}
@Override
public void dispense() {
// 发放商品并进入待机状态
System.out.println("Item " + vendingMachine.getItem() + " dispensed.");
vendingMachine.setState(new IdleState(vendingMachine));
}
}
最后,我们定义一个自动售货机类 VendingMachine
来管理自动售货机的状态:
javaCopy Codepublic class VendingMachine {
private String item;
private int price;
private int amount;
private VendingMachineState state;
public VendingMachine(String item, int price) {
this.item = item;
this.price = price;
this.amount = 0;
this.state = new IdleState(this);
}
public void selectItem(String item) {
state.selectItem(item);
}
public void insertMoney(int amount) {
state.insertMoney(amount);
}
public void dispense() {
state.dispense();
}
public String getItem() {
return item;
}
public void setItem(String item) {
this.item = item;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public int getAmount() {
return amount;
}
public void setAmount(int amount) {
this.amount = amount;
}
public void setState(VendingMachineState state) {
this.state = state;
}
}
现在,我们可以使用自动售货机类 VendingMachine
来创建一个自动售货机实例,并进行测试:
javaCopy CodeVendingMachine vendingMachine = new VendingMachine("Coke", 5);
// 初始状态为待机状态
vendingMachine.selectItem("Coke"); // 输出:Please insert money first.
// 插入 2 元钱后进入选购商品状态
vendingMachine.insertMoney(2); // 输出:2 yuan inserted.
vendingMachine.selectItem("Coke"); // 输出:Coke selected.
// 插入 3 元钱后进入支付状态
vendingMachine.insertMoney(3); // 输出:Current balance: 5
vendingMachine.insertMoney(1); // 输出:Item Coke dispensed.
// 发放商品后进入待机状态
vendingMachine.dispense(); // 输出:Please insert money first.
以上就是一个简单的自动售货机系统实例,使用了状态模式来实现不同状态之间的切换以及相应的行为。