概述
状态模式是一种行为设计模式,它允许对象在内部状态改变时改变它的行为。对象看起来似乎修改了它的类。这种模式主要用于当一个对象的行为依赖于它的状态,并且它必须在运行时根据状态改变它的行为。
目的
封装状态转换逻辑:将不同状态下对象的行为封装在不同的状态类中,使得状态转换的逻辑清晰且易于维护。
简化复杂的条件逻辑:避免使用大量的if-else或switch-case语句来处理各种状态下的行为,使代码更加结构化和易于理解。
增加可扩展性:新增状态时,只需添加新的状态类,不需要修改现有类的代码,符合开闭原则。
角色
Context(环境类):定义客户端感兴趣的接口,并且维护一个ConcreteState子类的实例,这个实例定义当前的状态。
State(状态接口):定义一个所有具体状态类都需要实现的接口,封装与Context的特定状态相关的行为。
ConcreteState(具体状态类):每个具体状态类实现State接口定义的一个行为,负责在Context处于该状态时的行为。
代码示例
假设我们正在设计一个简单的自动售货机系统,其状态包括“无硬币”、“有硬币”、“售出商品”等。我们可以使用状态模式来设计这个系统。
接口定义
public interface State {
void insertCoin();
void ejectCoin();
void dispense();
}
具体状态实现
public class NoCoinState implements State {
public void insertCoin() {
System.out.println("You inserted a coin.");
}
public void ejectCoin() {
System.out.println("You haven't inserted a coin.");
}
public void dispense() {
System.out.println("You need to pay first.");
}
}
// 类似的,可以定义 HasCoinState 和 SoldOutState 等其他状态类
环境类
public class VendingMachine {
private State state;
public VendingMachine() {
this.state = new NoCoinState();
}
public void setState(State state) {
this.state = state;
}
public void insertCoin() {
state.insertCoin();
}
public void ejectCoin() {
state.ejectCoin();
}
public void dispense() {
state.dispense();
}
}
客户端代码
VendingMachine vm = new VendingMachine();
vm.insertCoin(); // 输出 "You inserted a coin."
vm.dispense(); // 输出 "You need to pay first."
应用场景
当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变行为时。
当一个类中包含大量条件分支语句来处理不同状态时,这些条件分支可以被状态模式中的不同状态类替代。
需要让多个环境对象共享相同的状态对象,从而减少系统中对象的个数时。
状态模式通过将状态相关的逻辑分布到单独的状态类中,提高了代码的可读性和可维护性,是处理复杂状态变化逻辑的有效手段。
评论区