状态模式
简介
允许对象在内部状态改变时改变它的行为。
使用场景:
订单状态流转
TCP连接状态
游戏角色状态
工作流引擎
实现要点:
状态接口定义行为
具体状态类实现不同行为
上下文持有当前状态
UML
代码示例
订单实体类
@Data
public class Order {
private String orderId;
private String customerName;
private String userId;
private String productId;
private String productName;
private double amount;
private OrderStatusEnum status;
private Map<String, Object> orderData;
private long createdAt;
private long updatedAt;
// 构造函数
public Order() {
this.orderData = new HashMap<>();
}
public Order(String orderId, String customerName, String userId, String productId,
String productName, double amount, OrderStatusEnum status) {
this();
this.orderId = orderId;
this.customerName = customerName;
this.userId = userId;
this.productId = productId;
this.productName = productName;
this.amount = amount;
this.status = status;
this.createdAt = System.currentTimeMillis();
this.updatedAt = System.currentTimeMillis();
}
// 业务方法
public void updateStatus(OrderStatusEnum newStatus) {
this.status = newStatus;
this.updatedAt = System.currentTimeMillis();
}
public void addOrderData(String key, Object value) {
if (this.orderData == null) {
this.orderData = new HashMap<>();
}
this.orderData.put(key, value);
}
public Object getOrderData(String key) {
return this.orderData != null ? this.orderData.get(key) : null;
}
}
订单状态
public enum OrderStatusEnum {
PENDING_PAYMENT("PENDING_PAYMENT", "待支付"),
PAID("PAID", "已支付"),
SHIPPED("SHIPPED", "已发货"),
COMPLETED("COMPLETED", "已完成"),
CANCELLED("CANCELLED", "已取消"),
REFUNDING("REFUNDING", "退款中");
private final String code;
private final String name;
OrderStatusEnum(String code, String name) {
this.code = code;
this.name = name;
}
public String getCode() {
return code;
}
public String getName() {
return name;
}
}订单状态接口
public interface OrderState {
void pay(OrderContext context);
void deliver(OrderContext context);
void cancel(OrderContext context);
void complete(OrderContext context);
OrderStatusEnum getStatus();
}具体的状态
/**
* @author dcx
* @description 待支付状态
* @create 2025-01-27
*/
public class PendingPaymentState implements OrderState {
@Override
public void pay(OrderContext context) {
System.out.println("处理支付...");
if (Math.random() > 0.3) {
System.out.println("支付成功!");
context.changeState(OrderStatusEnum.PAID);
} else {
System.out.println("支付失败!");
context.changeState(OrderStatusEnum.CANCELLED);
}
}
@Override
public void deliver(OrderContext context) {
System.out.println("订单尚未支付,无法发货!");
}
@Override
public void cancel(OrderContext context) {
System.out.println("取消订单...");
context.changeState(OrderStatusEnum.CANCELLED);
}
@Override
public void complete(OrderContext context) {
System.out.println("订单尚未支付,无法完成!");
}
@Override
public OrderStatusEnum getStatus() {
return OrderStatusEnum.PENDING_PAYMENT;
}
}
/**
* @author dcx
* @description 已支付状态
* @create 2025-01-27
*/
public class PaidState implements OrderState {
@Override
public void pay(OrderContext context) {
System.out.println("订单已支付,无需重复支付!");
}
@Override
public void deliver(OrderContext context) {
System.out.println("开始发货...");
context.getOrderData().put("deliveryTime", System.currentTimeMillis());
context.getOrderData().put("trackingNumber", "TRK" + System.currentTimeMillis());
context.changeState(OrderStatusEnum.SHIPPED);
}
@Override
public void cancel(OrderContext context) {
System.out.println("订单已支付,需要退款处理...");
context.changeState(OrderStatusEnum.REFUNDING);
}
@Override
public void complete(OrderContext context) {
System.out.println("订单尚未发货,无法完成!");
}
@Override
public OrderStatusEnum getStatus() {
return OrderStatusEnum.PAID;
}
}
/**
* @author dcx
* @description 已取消状态
* @create 2025-01-27
*/
public class CancelledState implements OrderState {
@Override
public void pay(OrderContext context) {
System.out.println("订单已取消,无法支付!");
}
@Override
public void deliver(OrderContext context) {
System.out.println("订单已取消,无法发货!");
}
@Override
public void cancel(OrderContext context) {
System.out.println("订单已取消!");
}
@Override
public void complete(OrderContext context) {
System.out.println("订单已取消,无法完成!");
}
@Override
public OrderStatusEnum getStatus() {
return OrderStatusEnum.CANCELLED;
}
}
/**
* @author dcx
* @description 已发货状态
* @create 2025-01-27
*/
public class ShippedState implements OrderState {
@Override
public void pay(OrderContext context) {
System.out.println("订单已支付!");
}
@Override
public void deliver(OrderContext context) {
System.out.println("订单已发货!");
}
@Override
public void cancel(OrderContext context) {
System.out.println("订单已发货,无法取消!");
}
@Override
public void complete(OrderContext context) {
System.out.println("确认收货...");
context.getOrderData().put("completedTime", System.currentTimeMillis());
context.changeState(OrderStatusEnum.COMPLETED);
}
@Override
public OrderStatusEnum getStatus() {
return OrderStatusEnum.SHIPPED;
}
}
/**
* @author dcx
* @description 退款中状态
* @create 2025-01-27
*/
public class RefundingState implements OrderState {
@Override
public void pay(OrderContext context) {
System.out.println("订单退款中,无法支付!");
}
@Override
public void deliver(OrderContext context) {
System.out.println("订单退款中,无法发货!");
}
@Override
public void cancel(OrderContext context) {
System.out.println("订单退款中!");
}
@Override
public void complete(OrderContext context) {
System.out.println("退款处理完成...");
context.changeState(OrderStatusEnum.CANCELLED);
}
@Override
public OrderStatusEnum getStatus() {
return OrderStatusEnum.REFUNDING;
}
}
/**
* @author dcx
* @description 已完成状态
* @create 2025-01-27
*/
public class CompletedState implements OrderState {
@Override
public void pay(OrderContext context) {
System.out.println("订单已完成!");
}
@Override
public void deliver(OrderContext context) {
System.out.println("订单已完成!");
}
@Override
public void cancel(OrderContext context) {
System.out.println("订单已完成,无法取消!");
}
@Override
public void complete(OrderContext context) {
System.out.println("订单已完成!");
}
@Override
public OrderStatusEnum getStatus() {
return OrderStatusEnum.COMPLETED;
}
}订单状态工厂
public class OrderStateFactory {
public static OrderState createState(OrderStatusEnum status) {
switch (status) {
case PENDING_PAYMENT:
return new PendingPaymentState();
case PAID:
return new PaidState();
case SHIPPED:
return new ShippedState();
case COMPLETED:
return new CompletedState();
case CANCELLED:
return new CancelledState();
case REFUNDING:
return new RefundingState();
default:
throw new IllegalArgumentException("未知状态: " + status);
}
}
}订单上下文
public class OrderContext {
private OrderState currentState;
private Order order; // 使用Order类封装订单信息
// 构造函数 - 使用Order对象
public OrderContext(Order order) {
this.order = order;
// 根据订单状态初始化当前状态对象
this.currentState = OrderStateFactory.createState(order.getStatus());
}
// 状态转换方法
public void changeState(OrderStatusEnum newStatus) {
System.out.println("订单 " + order.getOrderId() + " 状态从 " +
order.getStatus().getName() + " 转换为 " + newStatus.getName());
// 更新订单状态
order.updateStatus(newStatus);
this.currentState = OrderStateFactory.createState(newStatus);
// 保存到数据库
saveToDatabase();
}
// 委托给当前状态处理的方法
public void pay() {
currentState.pay(this);
}
public void deliver() {
currentState.deliver(this);
}
public void cancel() {
currentState.cancel(this);
}
public void complete() {
currentState.complete(this);
}
// 模拟保存到数据库
private void saveToDatabase() {
System.out.println("保存订单状态到数据库: " + order.getOrderId() + " -> " + order.getStatus().getName());
// 这里应该是实际的数据库保存逻辑
// orderRepository.updateStatus(order.getOrderId(), order.getStatus().getCode(), order.getUpdatedAt());
}
// Getter方法
public OrderState getCurrentState() { return currentState; }
public Order getOrder() { return order; }
// 便捷方法,委托给Order对象
public String getOrderId() { return order.getOrderId(); }
public String getCustomerName() { return order.getCustomerName(); }
public double getAmount() { return order.getAmount(); }
public OrderStatusEnum getStatus() { return order.getStatus(); }
public java.util.Map<String, Object> getOrderData() { return order.getOrderData(); }
public long getCreatedAt() { return order.getCreatedAt(); }
public long getUpdatedAt() { return order.getUpdatedAt(); }
@Override
public String toString() {
return "OrderContext{" +
"order=" + order +
", currentState=" + currentState.getClass().getSimpleName() +
'}';
}
}订单服务
public class OrderService {
/**
* 从数据库加载订单
*/
public OrderContext loadOrderFromDatabase(String orderId) {
System.out.println("从数据库加载订单: " + orderId);
// 创建Order对象
Order order = new Order(
orderId,
"张三",
"USER001",
"PROD001",
"iPhone 15",
299.99,
OrderStatusEnum.PENDING_PAYMENT
);
// 设置订单数据
order.addOrderData("paymentMethod", "支付宝");
order.addOrderData("address", "北京市朝阳区");
order.addOrderData("phone", "13800138000");
// 设置时间
order.setCreatedAt(System.currentTimeMillis() - 86400000); // 1天前创建
order.setUpdatedAt(System.currentTimeMillis() - 3600000); // 1小时前更新
return new OrderContext(order);
}
/**
* 批量加载订单
*/
public List<OrderContext> loadOrdersByStatus(OrderStatusEnum status) {
System.out.println("从数据库加载状态为 " + status.getName() + " 的订单");
List<OrderContext> orders = new ArrayList<>();
// 模拟查询结果
for (int i = 1; i <= 3; i++) {
String orderId = "ORD" + String.format("%03d", i);
orders.add(loadOrderFromDatabase(orderId));
}
return orders;
}
/**
* 创建新订单
*/
public OrderContext createOrder(String customerName, String userId, String productId,
String productName, double amount) {
String orderId = "ORD" + System.currentTimeMillis();
Order order = new Order(
orderId,
customerName,
userId,
productId,
productName,
amount,
OrderStatusEnum.PENDING_PAYMENT
);
return new OrderContext(order);
}
}使用方式
public class OrderStatePatternTest {
/**
* 测试方法
*/
public static void main(String[] args) {
System.out.println("=== 使用Order类的状态模式演示 ===\n");
OrderService orderService = new OrderService();
// 1. 从数据库加载一个待支付的订单
System.out.println("=== 加载待支付订单 ===");
OrderContext order = orderService.loadOrderFromDatabase("ORD001");
System.out.println("加载的订单:" + order);
System.out.println("订单详情:" + order.getOrder());
System.out.println();
// 2. 继续处理这个订单
System.out.println("=== 继续处理订单 ===");
order.pay(); // 支付
order.deliver(); // 发货
order.complete(); // 完成
System.out.println();
// 3. 创建一个新订单
System.out.println("=== 创建新订单 ===");
OrderContext newOrder = orderService.createOrder(
"李四",
"USER002",
"PROD002",
"MacBook Pro",
12999.99
);
System.out.println("新订单:" + newOrder);
System.out.println("订单详情:" + newOrder.getOrder());
// 处理新订单
newOrder.pay();
newOrder.deliver();
newOrder.complete();
System.out.println();
// 4. 手动创建一个已支付的订单
System.out.println("=== 手动创建已支付订单 ===");
Order paidOrder = new Order(
"ORD003",
"王五",
"USER003",
"PROD003",
"iPad Air",
4999.99,
OrderStatusEnum.PAID
);
paidOrder.addOrderData("paymentMethod", "微信支付");
paidOrder.addOrderData("address", "上海市浦东新区");
paidOrder.setCreatedAt(System.currentTimeMillis() - 7200000); // 2小时前创建
paidOrder.setUpdatedAt(System.currentTimeMillis() - 1800000); // 30分钟前更新
OrderContext paidOrderContext = new OrderContext(paidOrder);
System.out.println("已支付订单:" + paidOrderContext);
// 继续处理
paidOrderContext.deliver(); // 发货
paidOrderContext.complete(); // 完成
System.out.println();
// 5. 批量处理待支付订单
System.out.println("=== 批量处理待支付订单 ===");
java.util.List<OrderContext> pendingOrders = orderService.loadOrdersByStatus(OrderStatusEnum.PENDING_PAYMENT);
for (OrderContext pendingOrder : pendingOrders) {
System.out.println("处理订单:" + pendingOrder.getOrderId() +
" - " + pendingOrder.getOrder().getProductName());
pendingOrder.pay();
System.out.println();
}
// 6. 测试状态工厂
System.out.println("=== 测试状态工厂 ===");
for (OrderStatusEnum status : OrderStatusEnum.values()) {
OrderState state = OrderStateFactory.createState(status);
System.out.println("状态: " + status.getName() + " -> 状态对象: " + state.getClass().getSimpleName());
}
System.out.println();
}
}
Last updated
Was this helpful?