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");
}
}
状态模式是管理对象状态变化的强大工具,特别适合处理复杂的状态流转逻辑。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播