状态
更新: 6/28/2025 字数: 0 字 时长: 0 分钟
定义
状态模式 (State Pattern) 允许一个对象在其内部状态改变时改变它的行为,使对象看起来似乎修改了它的类。该模式将状态封装成独立的类,并将动作委托到代表当前状态的对象。
角色
- 上下文 (Context):维护具体状态实例,定义客户端接口
- 抽象状态 (State):定义状态接口,封装上下文特定行为
- 具体状态 (ConcreteState):实现状态接口,每个子类对应一种状态
- 客户端 (Client):使用上下文对象,触发状态转换
实现
电梯状态控制
java
// 抽象状态
public interface ElevatorState {
void openDoors();
void closeDoors();
void move();
void stop();
}
// 具体状态:开门状态
public class OpenState implements ElevatorState {
private ElevatorContext context;
public OpenState(ElevatorContext context) {
this.context = context;
}
@Override
public void openDoors() {
System.out.println("门已经是开着的");
}
@Override
public void closeDoors() {
System.out.println("正在关门...");
context.setState(context.getClosedState());
}
@Override
public void move() {
System.out.println("无法移动,门开着");
}
@Override
public void stop() {
System.out.println("已经停止");
}
}
// 具体状态:关门状态
public class ClosedState implements ElevatorState {
private ElevatorContext context;
public ClosedState(ElevatorContext context) {
this.context = context;
}
@Override
public void openDoors() {
System.out.println("正在开门...");
context.setState(context.getOpenState());
}
@Override
public void closeDoors() {
System.out.println("门已经是关着的");
}
@Override
public void move() {
System.out.println("正在移动...");
context.setState(context.getMovingState());
}
@Override
public void stop() {
System.out.println("已经停止");
}
}
// 具体状态:移动状态
public class MovingState implements ElevatorState {
private ElevatorContext context;
public MovingState(ElevatorContext context) {
this.context = context;
}
@Override
public void openDoors() {
System.out.println("无法开门,正在移动");
}
@Override
public void closeDoors() {
System.out.println("门已经是关着的");
}
@Override
public void move() {
System.out.println("已经在移动中");
}
@Override
public void stop() {
System.out.println("正在停止...");
context.setState(context.getClosedState());
}
}
// 上下文:电梯控制
public class ElevatorContext {
private ElevatorState openState;
private ElevatorState closedState;
private ElevatorState movingState;
private ElevatorState currentState;
public ElevatorContext() {
openState = new OpenState(this);
closedState = new ClosedState(this);
movingState = new MovingState(this);
currentState = closedState; // 初始状态为关门
}
public void setState(ElevatorState state) {
this.currentState = state;
}
// 委托操作到当前状态
public void openDoors() {
currentState.openDoors();
}
public void closeDoors() {
currentState.closeDoors();
}
public void move() {
currentState.move();
}
public void stop() {
currentState.stop();
}
// 状态获取方法
public ElevatorState getOpenState() {
return openState;
}
public ElevatorState getClosedState() {
return closedState;
}
public ElevatorState getMovingState() {
return movingState;
}
}
// 使用示例
public class ElevatorDemo {
public static void main(String[] args) {
ElevatorContext elevator = new ElevatorContext();
elevator.openDoors(); // 开门
elevator.closeDoors(); // 关门
elevator.move(); // 移动
elevator.stop(); // 停止
elevator.openDoors(); // 开门
System.out.println("--- 尝试非法操作 ---");
elevator.move(); // 移动(失败,门开着)
elevator.closeDoors(); // 关门
elevator.move(); // 移动
}
}
订单状态系统
java
// 订单状态接口
public interface OrderState {
void confirm(OrderContext context);
void cancel(OrderContext context);
void ship(OrderContext context);
void deliver(OrderContext context);
}
// 具体状态:新建状态
public class NewState implements OrderState {
@Override
public void confirm(OrderContext context) {
System.out.println("订单已确认");
context.setState(context.getConfirmedState());
}
@Override
public void cancel(OrderContext context) {
System.out.println("订单已取消");
context.setState(context.getCancelledState());
}
@Override
public void ship(OrderContext context) {
System.out.println("订单未确认,无法发货");
}
@Override
public void deliver(OrderContext context) {
System.out.println("订单未发货,无法交付");
}
}
// 具体状态:已确认状态
public class ConfirmedState implements OrderState {
@Override
public void confirm(OrderContext context) {
System.out.println("订单已确认,无需重复操作");
}
@Override
public void cancel(OrderContext context) {
System.out.println("订单已取消");
context.setState(context.getCancelledState());
}
@Override
public void ship(OrderContext context) {
System.out.println("订单已发货");
context.setState(context.getShippedState());
}
@Override
public void deliver(OrderContext context) {
System.out.println("订单未发货,无法交付");
}
}
// 具体状态:已发货状态
public class ShippedState implements OrderState {
@Override
public void confirm(OrderContext context) {
System.out.println("订单已发货,无法确认");
}
@Override
public void cancel(OrderContext context) {
System.out.println("订单已发货,无法取消");
}
@Override
public void ship(OrderContext context) {
System.out.println("订单已发货,无需重复操作");
}
@Override
public void deliver(OrderContext context) {
System.out.println("订单已交付");
context.setState(context.getDeliveredState());
}
}
// 具体状态:已交付状态
public class DeliveredState implements OrderState {
@Override
public void confirm(OrderContext context) {
System.out.println("订单已完成,无法确认");
}
@Override
public void cancel(OrderContext context) {
System.out.println("订单已完成,无法取消");
}
@Override
public void ship(OrderContext context) {
System.out.println("订单已完成,无法发货");
}
@Override
public void deliver(OrderContext context) {
System.out.println("订单已完成,无需重复交付");
}
}
// 具体状态:已取消状态
public class CancelledState implements OrderState {
@Override
public void confirm(OrderContext context) {
System.out.println("订单已取消,无法确认");
}
@Override
public void cancel(OrderContext context) {
System.out.println("订单已取消,无需重复操作");
}
@Override
public void ship(OrderContext context) {
System.out.println("订单已取消,无法发货");
}
@Override
public void deliver(OrderContext context) {
System.out.println("订单已取消,无法交付");
}
}
// 上下文:订单
public class OrderContext {
private OrderState newState;
private OrderState confirmedState;
private OrderState shippedState;
private OrderState deliveredState;
private OrderState cancelledState;
private OrderState currentState;
public OrderContext() {
newState = new NewState();
confirmedState = new ConfirmedState();
shippedState = new ShippedState();
deliveredState = new DeliveredState();
cancelledState = new CancelledState();
currentState = newState; // 初始状态为新建
}
public void setState(OrderState state) {
this.currentState = state;
}
// 委托操作到当前状态
public void confirm() {
currentState.confirm(this);
}
public void cancel() {
currentState.cancel(this);
}
public void ship() {
currentState.ship(this);
}
public void deliver() {
currentState.deliver(this);
}
// 状态获取方法
public OrderState getNewState() {
return newState;
}
public OrderState getConfirmedState() {
return confirmedState;
}
public OrderState getShippedState() {
return shippedState;
}
public OrderState getDeliveredState() {
return deliveredState;
}
public OrderState getCancelledState() {
return cancelledState;
}
}
// 使用示例
public class OrderDemo {
public static void main(String[] args) {
OrderContext order = new OrderContext();
order.confirm(); // 确认
order.ship(); // 发货
order.deliver(); // 交付
System.out.println("\n--- 取消场景 ---");
OrderContext cancelledOrder = new OrderContext();
cancelledOrder.confirm(); // 确认
cancelledOrder.cancel(); // 取消
cancelledOrder.ship(); // 尝试发货(失败)
}
}
优缺点
优点:
- 状态转换显式化
- 消除条件分支语句
- 状态行为局部化
- 遵循开闭原则
- 状态对象可复用
- 提高可维护性
缺点:
- 状态类数量增加
- 上下文与状态耦合
- 状态转换逻辑可能复杂
- 状态共享困难
- 增加系统复杂度
- 性能开销(状态对象创建)
应用场景
- 工作流引擎
- 游戏角色状态
- 订单处理系统
- 网络协议状态机
- UI 控件状态
- 电梯控制系统
- 交通信号灯系统
- 自动售货机
与其他模式的关系
- 与策略模式:结构相似但目的不同(策略是算法选择,状态是行为随状态改变)
- 与享元模式:共享无状态的状态对象
- 与单例模式:状态对象可为单例
- 与组合模式:实现层次状态机
- 与备忘录模式:保存和恢复状态
- 与责任链模式:状态可委托到其他状态
JDK 中的状态模式
- Java 线程状态(Thread.State)
- Java FSM 框架(State Machine)
- Java AWT 组件状态
- Java Servlet 生命周期
- Spring 状态机(Spring StateMachine)
- Java NIO 通道状态(SelectionKey)
- Java 连接器状态(ConnectorState)
注意事项
- 状态转换控制(由谁管理转换)
- 状态共享策略
- 状态对象无状态化
- 处理状态初始化
- 避免状态循环依赖
- 状态层次结构设计
- 状态持久化策略
- 支持状态历史跟踪