状态模式
2/11/24About 5 min
状态模式允许对象在其内部状态改变时改变其行为,对象看起来似乎修改了它的类。

状态模式包含下列角色:
- 上下文(StateContext):
上下文是拥有状态的对象。它定义了客户端需要的接口,并维护一个当前状态对象的引用。 - 抽象状态角色(State):
抽象状态通常包含一些操作或方法,这些方法由具体状态类实现。 - 具体状态角色(Concrete State):
是抽象状态角色的实现,每个具体状态对应系统中的一个具体状态值。每个具体状态类都实现了抽象状态接口中定义的方法,并且可以改变环境对象的状态(即上下文的当前状态)。
代码实现
上下文
上下文具有两种状态切换的行为,即start、close两个方法。而且状态切换是由内部的state对象完成的。
public class StateContext {
private State state;
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
public void start() {
this.state.start(this);
}
public void close() {
this.state.close(this);
}
}抽象状态
抽象状态中定义了对象状态切换的方法。根据上下文对象可知,需要定义两个状态切换的操作。
public abstract class State {
public abstract void start(StateContext context);
public abstract void close(StateContext context);
}具体状态
由上下文可知,具体状态有两种(start,close)。下面分别为这两个状态定义对应的类,以及实现状态切换的方法。
public class StartState extends State {
@Override
public void start(StateContext context) {
System.out.println("已经处于start状态");
}
@Override
public void close(StateContext context) {
context.setState(new StopState());
System.out.println("start切换到close状态");
}
}同理可以写出StopState的实现。
public class StopState extends State {
@Override
public void start(StateContext context) {
context.setState(new StartState());
System.out.println("close切换到start状态");
}
@Override
public void close(StateContext context) {
System.out.println("已经处于close状态");
}
}使用
public class Client {
public static void main(String[] args) {
StateContext context = new StateContext();
context.setState(new StartState());
context.start();
context.close();
}
}运行结果:

状态模式与其他模式的对比
| 模式 | 功能 | 实现方式 | 适用场景 |
|---|---|---|---|
| 状态模式 | 封装对象状态行为 | 对象状态变化时改变其行为 | 对象行为依赖于其状态,且状态可动态变化时 |
| 策略模式 | 封装可替换算法 | 定义算法族,运行时动态切换 | 需要在运行时选择不同算法实现时 |
| 命令模式 | 封装请求为对象 | 将请求封装为命令,支持队列、撤销等操作 | 需要支持请求的队列化、日志记录或撤销时 |
| 模板方法模式 | 定义算法骨架 | 父类定义算法结构,子类实现具体步骤 | 多个类有相似算法结构,但具体实现不同时 |
总结
核心思想
状态模式的核心思想是将对象的状态封装为独立的状态类,使对象在内部状态改变时改变其行为。它通过将状态相关的行为转移到状态类中,避免了使用大量的条件判断语句,使代码更加清晰和可维护。
主要角色
- 上下文(StateContext):拥有状态的对象,维护当前状态引用,提供客户端接口
- 抽象状态(State):定义状态接口,包含状态相关的行为方法
- 具体状态(Concrete State):实现抽象状态接口,包含特定状态下的行为逻辑
实现方式
- 定义抽象状态接口,包含状态相关的行为方法
- 具体状态类实现抽象状态接口,实现特定状态下的行为
- 上下文类维护当前状态引用,提供状态切换的方法
- 客户端通过上下文对象调用状态相关的行为,状态切换由具体状态类内部实现
优缺点
优点:
- 符合单一职责原则,每个状态类只负责自己的行为
- 符合开放封闭原则,添加新状态只需添加新的状态类
- 避免了使用大量的条件判断语句,提高了代码的可维护性
- 状态切换逻辑集中在状态类中,便于理解和修改
- 状态类之间可以共享,减少了代码重复
缺点:
- 可能导致系统中状态类的数量增加
- 状态类之间可能存在依赖关系,增加了系统的复杂性
- 上下文类与状态类之间存在耦合,状态变化可能影响上下文
- 对于简单的状态切换,使用状态模式可能过于复杂
适用场景
- 对象行为依赖于其状态,且状态可动态变化
- 代码中包含大量与状态相关的条件判断语句
- 需要在运行时根据对象状态改变其行为
- 希望将状态相关的行为集中管理,提高代码的可维护性
- 需要实现状态的自动转换和状态历史记录
实际应用
- 订单状态管理:订单有多种状态(待支付、已支付、已发货、已完成等),不同状态下有不同的行为
- 工作流引擎:工作流节点有不同状态,状态变化触发不同的流程操作
- 游戏角色状态:游戏角色有多种状态(正常、受伤、死亡等),不同状态下有不同的行为
- 网络连接状态:网络连接有连接、断开、正在连接等状态,不同状态下有不同的处理逻辑
- 电梯运行状态:电梯有上行、下行、停止等状态,不同状态下有不同的运行逻辑