Java状态模式:对象状态变化管理
状态模式概述
状态模式(State Pattern)允许对象在内部状态改变时改变其行为,使对象看起来像修改了它的类。

核心结构
// 状态接口
interface State {
void handle(Context context);
}
// 上下文类
class Context {
private State currentState;
public Context() {
currentState = new ConcreteStateA(); // 初始状态
}
public void setState(State state) {
this.currentState = state;
}
public void request() {
currentState.handle(this);
}
}
完整示例:订单状态管理
// 1. 订单上下文
class OrderContext {
private OrderState currentState;
private String orderId;
public OrderContext(String orderId) {
this.orderId = orderId;
this.currentState = new NewOrderState(); // 初始状态
System.out.println("订单 " + orderId + " 创建,当前状态:新订单");
}
public void setState(OrderState state) {
this.currentState = state;
System.out.println("订单 " + orderId + " 状态变更:" + state.getStateName());
}
public String getOrderId() {
return orderId;
}
// 触发状态变化的方法
public void pay() {
currentState.pay(this);
}
public void ship() {
currentState.ship(this);
}
public void confirm() {
currentState.confirm(this);
}
public void cancel() {
currentState.cancel(this);
}
}
// 2. 状态接口
interface OrderState {
String getStateName();
void pay(OrderContext context);
void ship(OrderContext context);
void confirm(OrderContext context);
void cancel(OrderContext context);
}
// 3. 具体状态实现
// 新建订单状态
class NewOrderState implements OrderState {
@Override
public String getStateName() {
return "新订单";
}
@Override
public void pay(OrderContext context) {
System.out.println("支付成功,订单进入待发货状态");
context.setState(new PaidState());
}
@Override
public void ship(OrderContext context) {
System.out.println("错误:新订单不能直接发货,请先支付");
}
@Override
public void confirm(OrderContext context) {
System.out.println("错误:新订单不能确认收货");
}
@Override
public void cancel(OrderContext context) {
System.out.println("订单取消成功");
context.setState(new CancelledState());
}
}
// 已支付状态
class PaidState implements OrderState {
@Override
public String getStateName() {
return "已支付";
}
@Override
public void pay(OrderContext context) {
System.out.println("错误:订单已支付,不能重复支付");
}
@Override
public void ship(OrderContext context) {
System.out.println("商品已发货");
context.setState(new ShippedState());
}
@Override
public void confirm(OrderContext context) {
System.out.println("错误:已支付订单不能确认收货,请等待发货");
}
@Override
public void cancel(OrderContext context) {
System.out.println("订单已取消,退款处理中");
context.setState(new CancelledState());
}
}
// 已发货状态
class ShippedState implements OrderState {
@Override
public String getStateName() {
return "已发货";
}
@Override
public void pay(OrderContext context) {
System.out.println("错误:已发货订单不需要支付");
}
@Override
public void ship(OrderContext context) {
System.out.println("错误:订单已发货");
}
@Override
public void confirm(OrderContext context) {
System.out.println("确认收货成功");
context.setState(new CompletedState());
}
@Override
public void cancel(OrderContext context) {
System.out.println("订单已取消,请等待快递退回");
context.setState(new CancelledState());
}
}
// 已完成状态
class CompletedState implements OrderState {
@Override
public String getStateName() {
return "已完成";
}
@Override
public void pay(OrderContext context) {
System.out.println("错误:已完成订单不需要支付");
}
@Override
public void ship(OrderContext context) {
System.out.println("错误:已完成订单不能发货");
}
@Override
public void confirm(OrderContext context) {
System.out.println("错误:订单已完成");
}
@Override
public void cancel(OrderContext context) {
System.out.println("错误:已完成订单不能取消");
}
}
// 已取消状态
class CancelledState implements OrderState {
@Override
public String getStateName() {
return "已取消";
}
@Override
public void pay(OrderContext context) {
System.out.println("错误:已取消订单不能支付");
}
@Override
public void ship(OrderContext context) {
System.out.println("错误:已取消订单不能发货");
}
@Override
public void confirm(OrderContext context) {
System.out.println("错误:已取消订单不能确认收货");
}
@Override
public void cancel(OrderContext context) {
System.out.println("错误:订单已取消");
}
}
使用示例
public class StatePatternDemo {
public static void main(String[] args) {
System.out.println("=== 订单状态管理示例 ===\n");
// 创建订单
OrderContext order = new OrderContext("ORD-2024-001");
// 模拟正常流程
System.out.println("\n1. 正常处理流程:");
order.pay(); // 新订单 -> 已支付
order.ship(); // 已支付 -> 已发货
order.confirm(); // 已发货 -> 已完成
// 创建新订单测试异常流程
System.out.println("\n2. 异常操作流程:");
OrderContext order2 = new OrderContext("ORD-2024-002");
order2.ship(); // 错误:新订单不能发货
order2.pay(); // 新订单 -> 已支付
order2.pay(); // 错误:不能重复支付
// 创建新订单测试取消流程
System.out.println("\n3. 取消流程:");
OrderContext order3 = new OrderContext("ORD-2024-003");
order3.cancel(); // 新订单 -> 已取消
order3.pay(); // 错误:已取消不能支付
}
}
高级应用:工作流引擎
// 更复杂的状态机实现
interface WorkflowState {
boolean canTransitionTo(WorkflowState targetState);
void onEnter(WorkflowContext context);
void onExit(WorkflowContext context);
List<String> getAllowedActions();
}
class WorkflowContext {
private WorkflowState state;
private Map<String, Object> data;
private List<StateTransition> history;
public boolean transitionTo(WorkflowState newState) {
if (!state.canTransitionTo(newState)) {
return false;
}
state.onExit(this);
state = newState;
state.onEnter(this);
history.add(new StateTransition(newState, new Date()));
return true;
}
}
状态模式的优缺点
优点:
- ✅ 封装了状态转换规则
- ✅ 易于添加新状态
- ✅ 消除大量条件判断语句
- ✅ 提高代码的可维护性
缺点:
- ❌ 类数量增加
- ❌ 状态转换逻辑可能分散
- ❌ 状态类之间可能有依赖
适用场景
- 对象行为依赖于其状态,且状态变化频繁
- 操作包含大量条件语句,且条件依赖于对象状态
- 状态转换规则复杂,需要集中管理
Spring框架中的应用
// Spring State Machine (Spring Statemachine)
@Configuration
@EnableStateMachine
public class OrderStateMachineConfig
extends StateMachineConfigurerAdapter<String, String> {
@Override
public void configure(StateMachineStateConfigurer<String, String> states)
throws Exception {
states
.withStates()
.initial("NEW")
.state("PAID")
.state("SHIPPED")
.state("COMPLETED")
.end("CANCELLED");
}
@Override
public void configure(StateMachineTransitionConfigurer<String, String> transitions)
throws Exception {
transitions
.withExternal()
.source("NEW").target("PAID")
.event("PAY")
.and()
.withExternal()
.source("PAID").target("SHIPPED")
.event("SHIP");
}
}
状态模式是管理对象状态变化的强大工具,特别适合处理复杂的状态流转逻辑。