1. 项目结构
- 项目结构
bash
state-pattern-demo/
├── pom.xml
├── src/
│ └── main/
│ └── java/
│ └── com/
│ └── example/
│ └── state/
│ ├── context/
│ │ └── OrderContext.java
│ ├── state/
│ │ ├── OrderState.java
│ │ ├── NewState.java
│ │ ├── PaidState.java
│ │ ├── ShippedState.java
│ │ ├── DeliveredState.java
│ │ └── CancelledState.java
│ └── Main.java
- Maven配置文件 (pom.xml)
xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>state-pattern-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
2. 代码实现
-
OrderState.java (状态接口)
javapackage com.example.state.state; /** * 订单状态接口 * 定义订单所有可能的行为 */ public interface OrderState { /** * 支付订单 */ void pay(OrderContext context); /** * 发货 */ void ship(OrderContext context); /** * 确认收货 */ void receive(OrderContext context); /** * 取消订单 */ void cancel(OrderContext context); /** * 获取当前状态名称 */ String getStateName(); } -
NewState.java (新建状态)
javapackage com.example.state.state; import com.example.state.context.OrderContext; /** * 新建状态 - 订单刚创建 */ public class NewState implements OrderState { @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 receive(OrderContext context) { System.out.println("订单未发货,不能收货"); } @Override public void cancel(OrderContext context) { System.out.println("订单已取消"); context.setState(new CancelledState()); } @Override public String getStateName() { return "新建状态"; } } -
PaidState.java (已支付状态)
javapackage com.example.state.state; import com.example.state.context.OrderContext; /** * 已支付状态 */ public class PaidState implements OrderState { @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 receive(OrderContext context) { System.out.println("订单未发货,不能收货"); } @Override public void cancel(OrderContext context) { System.out.println("订单已取消,将进行退款处理"); context.setState(new CancelledState()); } @Override public String getStateName() { return "已支付状态"; } } -
ShippedState.java (已发货状态)
javapackage com.example.state.state; import com.example.state.context.OrderContext; /** * 已发货状态 */ public class ShippedState implements OrderState { @Override public void pay(OrderContext context) { System.out.println("订单已支付,无需重复支付"); } @Override public void ship(OrderContext context) { System.out.println("订单已发货,无需重复发货"); } @Override public void receive(OrderContext context) { System.out.println("订单已确认收货"); context.setState(new DeliveredState()); } @Override public void cancel(OrderContext context) { System.out.println("订单已发货,无法取消,请联系客服处理"); } @Override public String getStateName() { return "已发货状态"; } } -
DeliveredState.java (已收货状态)
javapackage com.example.state.state; import com.example.state.context.OrderContext; /** * 已收货状态 - 最终状态 */ public class DeliveredState implements OrderState { @Override public void pay(OrderContext context) { System.out.println("订单已完成,无需支付"); } @Override public void ship(OrderContext context) { System.out.println("订单已完成,无需发货"); } @Override public void receive(OrderContext context) { System.out.println("订单已完成,无需重复确认收货"); } @Override public void cancel(OrderContext context) { System.out.println("订单已完成,无法取消"); } @Override public String getStateName() { return "已收货状态"; } } -
CancelledState.java (已取消状态)
javapackage com.example.state.state; import com.example.state.context.OrderContext; /** * 已取消状态 - 最终状态 */ public class CancelledState implements OrderState { @Override public void pay(OrderContext context) { System.out.println("订单已取消,无法支付"); } @Override public void ship(OrderContext context) { System.out.println("订单已取消,无法发货"); } @Override public void receive(OrderContext context) { System.out.println("订单已取消,无法收货"); } @Override public void cancel(OrderContext context) { System.out.println("订单已取消,无需重复取消"); } @Override public String getStateName() { return "已取消状态"; } } -
OrderContext.java
javapackage com.example.state.context; import com.example.state.state.OrderState; import com.example.state.state.NewState; /** * 订单上下文 - 维护当前状态 */ public class OrderContext { private OrderState currentState; private String orderId; public OrderContext(String orderId) { this.orderId = orderId; // 初始状态为新建状态 this.currentState = new NewState(); System.out.println("订单 [" + orderId + "] 创建成功,初始状态: " + currentState.getStateName()); } /** * 设置新的状态 */ public void setState(OrderState state) { this.currentState = state; System.out.println("订单 [" + orderId + "] 状态变更为: " + state.getStateName()); } /** * 获取当前状态 */ public OrderState getState() { return currentState; } /** * 支付订单 */ public void pay() { System.out.print("执行支付操作: "); currentState.pay(this); } /** * 发货 */ public void ship() { System.out.print("执行发货操作: "); currentState.ship(this); } /** * 确认收货 */ public void receive() { System.out.print("执行收货操作: "); currentState.receive(this); } /** * 取消订单 */ public void cancel() { System.out.print("执行取消操作: "); currentState.cancel(this); } /** * 显示当前状态 */ public void displayCurrentState() { System.out.println("订单 [" + orderId + "] 当前状态: " + currentState.getStateName()); } public String getOrderId() { return orderId; } }- Main.java
javapackage com.example.state; import com.example.state.context.OrderContext; /** * 状态模式演示主类 */ public class Main { public static void main(String[] args) { System.out.println("=== 状态模式演示 - 订单状态流转 ==="); System.out.println(); // 创建订单 OrderContext order = new OrderContext("ORD2023001"); order.displayCurrentState(); System.out.println("\n--- 正常流程测试 ---"); // 正常流程:新建 -> 支付 -> 发货 -> 收货 order.pay(); order.ship(); order.receive(); // 尝试在已完成状态下执行操作 order.pay(); order.cancel(); System.out.println("\n--- 取消流程测试 ---"); // 新建另一个订单 OrderContext order2 = new OrderContext("ORD2023002"); // 取消订单 order2.cancel(); // 尝试在已取消状态下执行操作 order2.pay(); order2.ship(); System.out.println("\n--- 非法操作测试 ---"); // 新建订单 OrderContext order3 = new OrderContext("ORD2023003"); // 尝试在新建状态下直接发货(非法操作) order3.ship(); // 尝试在新建状态下直接收货(非法操作) order3.receive(); // 正常支付 order3.pay(); // 尝试重复支付 order3.pay(); // 发货 order3.ship(); // 尝试在已发货状态下取消订单 order3.cancel(); // 正常收货 order3.receive(); System.out.println("\n=== 演示结束 ==="); } }
3. 构建和运行
-
编译项目
bashmvn clean compile -
运行主程序
bashmvn exec:java -Dexec.mainClass="com.example.state.Main"
4. 核心概念
- 要点:
- 状态接口 (OrderState): 定义所有状态共有的行为
- 具体状态类: 实现状态接口,封装特定状态下的行为
- 上下文类 (OrderContext): 维护当前状态,并将行为委托给当前状态对象
- 状态转换: 由具体状态类决定下一个状态是什么
- 优势
- 单一职责原则: 每个状态类只负责自己状态的行为
- 开闭原则: 新增状态只需添加新类,无需修改现有代码
- 消除条件语句: 避免了大量的if-else或switch-case语句
- 状态转换逻辑明确: 状态转换逻辑分布在各个状态类中,更加清晰
- 适用场景
- 对象的行为取决于它的状态,并且必须在运行时根据状态改变行为
- 操作中包含大量与对象状态相关的条件语句
- 状态数量较多,且状态转换逻辑复杂