Java行为型模式---状态模式
·

状态模式(State Pattern)详解
概念与定义
状态模式(State Pattern)是一种行为设计模式,它允许对象在内部状态改变时改变它的行为,使对象看起来像是修改了它的类。状态模式将状态封装成独立的类,并将动作委托到代表当前状态的对象。
核心思想
状态模式的核心是将状态与行为绑定,每个状态对应一个类,这些类实现相同的接口或继承相同的抽象类。这样,当对象的内部状态发生变化时,可以简单地切换到不同的状态类实例,从而改变对象的行为表现。
关键特点
- 状态对象化:将每个状态封装为一个独立的对象
- 行为委托:上下文对象将状态相关行为委托给当前状态对象
- 状态转换:状态对象可以负责状态之间的转换逻辑
典型结构
状态模式通常包含以下主要角色:
- Context(上下文):维护一个具体状态对象的实例,定义客户端需要的接口
- State(抽象状态):定义一个接口以封装与Context的特定状态相关的行为
- ConcreteState(具体状态):实现与Context的某个状态相关的行为
应用场景
状态模式特别适用于以下情形:
- 对象的行为取决于它的状态,并且必须在运行时根据状态改变行为
- 操作中包含大量的条件语句,这些条件语句依赖于对象的状态
- 状态转换逻辑复杂,或者状态数量较多的情况
实际示例
例如在一个订单处理系统中:
- 订单可能有"待支付"、"已支付"、"已发货"、"已完成"等不同状态
- 每个状态下的取消操作、修改操作等行为都不同
- 使用状态模式可以将每个状态及其行为封装为单独的类
优势
- 单一职责原则:将与特定状态相关的代码放在单独的类中
- 开闭原则:可以方便地引入新的状态而不需要修改现有状态类
- 消除条件语句:避免了大型的条件状态选择语句
- 状态转换显式化:使状态转换更加明确和可管理
核心组成部分
-
Context(环境类)
- 定义客户端感兴趣的接口
- 维护一个ConcreteState子类的实例,这个实例定义当前状态
- 示例:订单系统、电梯控制系统等
-
State(抽象状态类)
- 定义一个接口以封装与Context的一个特定状态相关的行为
- 示例:
OrderState接口定义订单在不同状态下的行为
-
ConcreteState(具体状态类)
- 每一个子类实现一个与Context的一个状态相关的行为
- 示例:
NewOrderState、PaidOrderState、ShippedOrderState等
实现示例
// 状态接口
public interface OrderState {
void handlePayment(OrderContext context);
void handleShipping(OrderContext context);
void handleCancel(OrderContext context);
}
// 具体状态类:新订单状态
public class NewOrderState implements OrderState {
@Override
public void handlePayment(OrderContext context) {
System.out.println("处理付款,订单状态变更为已付款");
context.setState(new PaidOrderState());
}
@Override
public void handleShipping(OrderContext context) {
System.out.println("错误:新订单不能直接发货");
}
@Override
public void handleCancel(OrderContext context) {
System.out.println("订单已取消");
context.setState(new CancelledOrderState());
}
}
// 上下文类
public class OrderContext {
private OrderState currentState;
public OrderContext() {
this.currentState = new NewOrderState();
}
public void setState(OrderState state) {
this.currentState = state;
}
public void processPayment() {
currentState.handlePayment(this);
}
public void processShipping() {
currentState.handleShipping(this);
}
public void cancelOrder() {
currentState.handleCancel(this);
}
}
应用场景
-
订单处理系统
- 订单从"新建"到"已付款"、"已发货"、"已完成"或"已取消"的状态转换
-
游戏开发
- 游戏角色在不同状态下的行为(站立、行走、奔跑、跳跃等)
-
工作流引擎
- 文档审批流程中的状态转换(草稿、待审批、已批准、已拒绝等)
-
UI组件
- 按钮在不同状态下的显示和行为(正常、悬停、按下、禁用等)
优缺点分析
优点:
- 将特定状态相关的行为局部化,并且将不同状态的行为分割开来
- 使得状态转换显式化
- State对象可被共享(如果它们没有内部状态)
缺点:
- 导致系统中类的数量增加
- 当状态转换规则复杂时,Context类可能变得难以维护
- 对"开闭原则"的支持并不完美,新增状态类需要修改负责状态转换的代码
实际应用案例:电商平台订单系统状态管理
-
订单状态转换流程详解:
- New(新建):用户提交订单后的初始状态
- Paid(已支付):用户完成支付后的状态
- Processing(处理中):商家开始备货和打包
- Shipped(已发货):商品出库并交由物流运输
- Delivered(已送达):客户签收确认
- Cancelled(已取消):订单在任何状态都可能被取消
-
状态相关行为详细说明:
-
新订单行为:
- 支付操作:调用支付接口
- 取消操作:直接关闭订单
- 示例:用户提交订单后30分钟内未支付自动取消
-
已付款订单行为:
- 退货:生成退货申请单
- 发货:打印物流面单
- 示例:支付后24小时内未发货需补偿优惠券
-
已发货订单行为:
- 确认收货:触发结算流程
- 物流跟踪:提供实时物流信息
- 示例:发货后7天自动确认收货
-
已完成订单行为:
- 评价:开放评价入口
- 售后:开启售后服务通道
- 示例:确认收货后15天内可申请售后
-
-
状态转换条件检查实现细节:
-
发货前检查:
- 支付状态校验
- 库存占用确认
- 地址有效性验证
- 示例代码:
if(!order.isPaid()){ throw new IllegalStateException("未支付订单不能发货"); }
-
取消订单检查:
- 发货状态判断
- 退款流程触发
- 库存释放处理
- 示例场景:已发货订单需先拦截物流才能取消
-
-
状态模式优势体现:
- 将业务规则分散到各状态类中:
- OrderState接口定义公共方法
- PaidState实现已支付状态特有逻辑
- ShippedState处理物流相关操作
- 避免庞大if-else判断:
// 传统方式 if(state == NEW){ // 处理新建逻辑 }else if(state == PAID){ // 处理支付逻辑 } //... // 状态模式 currentState.handleRequest(); - 扩展性:新增状态只需添加新类,不影响现有代码
- 将业务规则分散到各状态类中:
更多推荐



所有评论(0)