一、简介
状态模式(State Pattern)是一种行为设计模式,它允许对象在其内部状态发生改变时改变其行为。该模式主要用于根据对象的内部状态使其行为不同。在状态模式中,对象的行为会根据内部状态的变化而变化。它包含了以下关键角色:
- 环境(Context):环境类持有一个状态对象,并在状态对象之间进行切换。它会委托给当前状态对象处理请求。
- 抽象状态(State):定义了一个接口或抽象类,用于封装特定状态下的行为。所有具体状态类都必须实现这个抽象状态,以便在环境对象中切换状态。
- 具体状态(Concrete State):实现了抽象状态定义的接口或抽象类,并且负责具体状态下的行为。
状态模式的核心思想是将对象的各种状态抽象为独立的类,让对象在不同的状态下具有不同的行为。通过将每个状态封装成类,可以避免在环境类中出现大量的条件判断语句。这样可以提高代码的可读性、可维护性和可扩展性。
总的来说,状态模式能够使得对象在不同状态下能够有不同的行为表现,并将状态转换的逻辑分离到不同的状态类中,从而简化了代码结构,降低了复杂性。
二、状态模式
自动售货机根据它的状态(有货物、无货物、付款中、售出等)采取不同的行为。
2.1、状态接口
// 状态接口
interface VendingMachineState {
void pressButton();
void insertCoin();
void dispenseItem();
}
2.2、具体状态类
// 具体状态类 - 有商品
public class HasProductState implements VendingMachineState {
@Override
public void pressButton() {
System.out.println("选择商品");
}
@Override
public void insertCoin() {
System.out.println("投入硬币");
}
@Override
public void dispenseItem() {
System.out.println("出售商品");
}
}
// 具体状态类 - 无商品
public class NoProductState implements VendingMachineState {
@Override
public void pressButton() {
System.out.println("没有商品可售");
}
@Override
public void insertCoin() {
System.out.println("没有商品可售");
}
@Override
public void dispenseItem() {
System.out.println("没有商品可售");
}
}
2.3、上下文
// 自动售货机类(上下文)
public class VendingMachine {
private VendingMachineState currentState;
public VendingMachine() {
currentState = new NoProductState(); // 初始状态为无货物
}
public void setState(VendingMachineState state) {
currentState = state;
}
public void insertCoin() {
currentState.insertCoin();
}
public void pressButton() {
currentState.pressButton();
currentState.dispenseItem();
}
}
2.4、使用
public class StatePatternExample {
public static void main(String[] args) {
VendingMachine vendingMachine = new VendingMachine();
vendingMachine.pressButton();
vendingMachine.insertCoin();
vendingMachine.setState(new HasProductState()); // 改变状态为有商品
vendingMachine.pressButton();
vendingMachine.insertCoin();
}
}
运行结果:
没有商品可售
没有商品可售
没有商品可售
选择商品
出售商品
投入硬币
在这个示例中,自动售货机(VendingMachine)根据状态(VendingMachineState)的不同,会执行不同的行为。当状态改变时,自动售货机的行为也随之改变。
三、优点与缺点
状态模式具有以下优点和缺点:
优点
- 清晰的状态转换: 将每个状态封装到一个类中,使状态转换更加明确和清晰。
- 减少条件语句: 避免了大量的条件语句,使代码更加简洁、可读性更高。
- 单一职责原则: 将状态封装到不同的类中,每个类负责自己的状态行为,遵循了单一职责原则。
- 增加新状态容易: 添加新的状态类相对容易,不会影响现有状态类的行为。
- 提高可维护性: 通过将状态逻辑分散到不同的类中,易于维护和修改。
缺点
- 增加类和对象数量: 每个状态都可能需要一个对应的类,这可能会导致类的数量增加,使得代码更加复杂。
- 状态切换过多: 如果状态转换较为频繁且状态之间切换关系复杂,可能会增加管理难度。
- 可能引入过多细粒度的类: 过多的状态类可能会导致类的数量增加,增加系统复杂性。
总的来说,状态模式适用于需要对象根据其内部状态改变行为的情况,能够有效减少条件语句、提高代码的可读性和可维护性。但如果状态过于简单或状态转换频繁,可能会引入过多细粒度的类,导致管理和维护的困难。选择使用状态模式时,需根据具体情况权衡利弊。