Solon状态机:复杂业务流程管理

Solon状态机:复杂业务流程管理

【免费下载链接】solon 🔥 面向全场景的 Java 企业级应用开发框架:克制、高效、开放、生态!并发高 700%;内存省 50%;启动快 10 倍;打包小 90%;同时兼容 java8 ~ java24。(对标“美国博通公司”(Broadcom)的 Spring 生态) 【免费下载链接】solon 项目地址: https://gitcode.com/opensolon/solon

痛点:业务状态流转的复杂性挑战

在日常业务开发中,你是否经常遇到这样的困境?

  • 订单状态流转逻辑散落在各个Service方法中,难以维护
  • 状态转换条件复杂,if-else嵌套越来越深
  • 新增状态或事件时,需要修改多处代码,容易遗漏
  • 缺乏统一的状态转换规则管理,可读性差
  • 并发场景下状态转换存在竞态条件风险

Solon状态机(StateMachine)模块正是为了解决这些痛点而生,提供了一套声明式、线程安全的状态管理解决方案。

Solon状态机核心架构

状态机核心类图

mermaid

核心组件说明

组件泛型参数说明
StateMachine<S,E,T>S: 状态类型, E: 事件类型, T: 负载类型状态机主体,管理所有状态转换规则
StateTransitionDecl<S,E,T>同上状态转换声明,用于定义转换规则
EventContext<S,T>S: 状态类型, T: 负载类型事件上下文接口,提供当前状态和负载数据
StateTransitionContext<S,E,T>S: 状态类型, E: 事件类型, T: 负载类型状态转换上下文,包含完整的转换信息

实战:订单状态机完整示例

1. 定义状态和事件枚举

// 订单状态枚举
public enum OrderStatus {
    WAITING_PAYMENT,    // 待支付
    WAITING_RECEIVE,    // 待收货  
    FINISHED,           // 已完成
    CANCELED            // 已取消
}

// 订单事件枚举
public enum OrderEvent {
    CREATE_ORDER,       // 创建订单
    PAY_ORDER,          // 支付订单
    RECEIVE_ORDER,      // 确认收货
    CANCEL_ORDER,       // 取消订单
    FINISH_ORDER        // 完成订单
}

2. 实现事件上下文实体

public class Order implements EventContext<OrderStatus, Order> {
    private final String orderId;
    private OrderStatus status;
    private BigDecimal amount;
    private LocalDateTime createTime;

    public Order(String orderId, OrderStatus status) {
        this.orderId = orderId;
        this.status = status;
        this.createTime = LocalDateTime.now();
    }

    // Getter/Setter 方法...

    @Override
    public OrderStatus getCurrentState() {
        return status;
    }

    @Override
    public Order getPayload() {
        return this;
    }
}

3. 构建完整的状态机配置

@Managed
public class OrderStateMachine extends StateMachine<OrderStatus, OrderEvent, Order> {
    
    public OrderStateMachine() {
        // 创建订单:初始状态 -> 待支付
        from(null).to(OrderStatus.WAITING_PAYMENT).on(OrderEvent.CREATE_ORDER)
                .then(context -> {
                    Order order = context.getPayload();
                    order.setStatus(context.getTo());
                    System.out.println("订单创建成功:" + order.getOrderId());
                });

        // 支付订单:待支付 -> 待收货
        from(OrderStatus.WAITING_PAYMENT).to(OrderStatus.WAITING_RECEIVE).on(OrderEvent.PAY_ORDER)
                .when(context -> {
                    Order order = context.getPayload();
                    // 检查支付金额是否足够
                    return order.getAmount().compareTo(BigDecimal.ZERO) > 0;
                })
                .then(context -> {
                    Order order = context.getPayload();
                    order.setStatus(context.getTo());
                    System.out.println("订单支付成功:" + order.getOrderId());
                });

        // 确认收货:待收货 -> 已完成
        from(OrderStatus.WAITING_RECEIVE).to(OrderStatus.FINISHED).on(OrderEvent.RECEIVE_ORDER)
                .then(context -> {
                    Order order = context.getPayload();
                    order.setStatus(context.getTo());
                    System.out.println("订单已完成:" + order.getOrderId());
                });

        // 取消订单:待支付 -> 已取消
        from(OrderStatus.WAITING_PAYMENT).to(OrderStatus.CANCELED).on(OrderEvent.CANCEL_ORDER)
                .when(context -> {
                    Order order = context.getPayload();
                    // 只能取消24小时内的订单
                    return order.getCreateTime().isAfter(LocalDateTime.now().minusHours(24));
                })
                .then(context -> {
                    Order order = context.getPayload();
                    order.setStatus(context.getTo());
                    System.out.println("订单已取消:" + order.getOrderId());
                });
    }
}

4. 业务服务层使用

@Managed
public class OrderService {
    
    @Inject
    private OrderStateMachine orderStateMachine;

    /**
     * 创建订单
     */
    public Order createOrder(String orderId, BigDecimal amount) {
        Order order = new Order(orderId, null);
        order.setAmount(amount);
        
        orderStateMachine.sendEvent(OrderEvent.CREATE_ORDER, order);
        return order;
    }

    /**
     * 支付订单
     */
    public Order payOrder(String orderId) {
        Order order = findOrderById(orderId);
        
        try {
            orderStateMachine.sendEvent(OrderEvent.PAY_ORDER, order);
            return order;
        } catch (IllegalStateException e) {
            throw new BusinessException("订单支付失败:" + e.getMessage());
        }
    }

    /**
     * 取消订单
     */
    public Order cancelOrder(String orderId) {
        Order order = findOrderById(orderId);
        
        try {
            orderStateMachine.sendEvent(OrderEvent.CANCEL_ORDER, order);
            return order;
        } catch (IllegalStateException e) {
            throw new BusinessException("订单取消失败:" + e.getMessage());
        }
    }
}

状态转换流程图

mermaid

高级特性详解

1. 条件判断(when条件)

// 复杂的条件判断
.when(context -> {
    Order order = context.getPayload();
    return order.getAmount().compareTo(new BigDecimal("100")) >= 0 && 
           order.getCreateTime().isAfter(LocalDateTime.now().minusDays(7));
})

2. 执行动作(then动作)

// 复杂的执行动作
.then(context -> {
    Order order = context.getPayload();
    order.setStatus(context.getTo());
    order.setUpdateTime(LocalDateTime.now());
    
    // 发送消息通知
    messageService.sendOrderStatusChange(order);
    
    // 记录操作日志
    logService.recordOrderOperation(order, context.getEvent());
})

3. 多源状态转换

// 从多个状态转换到同一目标状态
from(OrderStatus.WAITING_PAYMENT, OrderStatus.WAITING_RECEIVE)
    .to(OrderStatus.CANCELED)
    .on(OrderEvent.CANCEL_ORDER)
    .then(context -> {
        // 取消订单逻辑
    });

并发安全与性能优化

线程安全机制

Solon状态机内置ReentrantLock确保线程安全:

public S sendEvent(E event, EventContext<S, T> eventContext) {
    LOCKER.lock();
    try {
        // 状态转换逻辑
    } finally {
        LOCKER.unlock();
    }
}

性能优化建议

优化策略实施方法效果
状态机复用使用@Managed注解管理单例减少对象创建开销
预编译规则在构造函数中初始化所有转换规则避免运行时动态添加
条件优化将频繁失败的条件放在前面提前终止匹配过程
缓存策略对不变的状态机进行缓存减少重复初始化

最佳实践指南

1. 状态机设计原则

mermaid

2. 错误处理策略

public class OrderService {
    
    public Order processOrderEvent(String orderId, OrderEvent event) {
        Order order = findOrderById(orderId);
        
        try {
            orderStateMachine.sendEvent(event, order);
            return order;
        } catch (IllegalStateException e) {
            // 状态转换失败处理
            log.warn("状态转换失败: orderId={}, event={}, error={}", 
                    orderId, event, e.getMessage());
            throw new BusinessException("操作失败:" + e.getMessage());
        } catch (Exception e) {
            // 其他异常处理
            log.error("系统异常: orderId={}, event={}", orderId, event, e);
            throw new SystemException("系统繁忙,请稍后重试");
        }
    }
}

3. 测试策略

测试类型测试内容测试方法
单元测试单个状态转换规则Mock事件上下文,验证转换结果
集成测试完整业务流程模拟真实业务场景,验证端到端流程
并发测试多线程状态转换使用并发测试工具验证线程安全性

总结与展望

Solon状态机模块为复杂业务流程管理提供了强大的解决方案:

核心价值:

  • ✅ 声明式配置,代码清晰易维护
  • ✅ 线程安全,支持高并发场景
  • ✅ 条件判断灵活,支持复杂业务规则
  • ✅ 扩展性强,易于新增状态和事件

适用场景:

  • 电商订单管理系统
  • 工作流审批流程
  • 游戏状态管理
  • IoT设备状态监控
  • 金融交易状态跟踪

通过本文的详细讲解和实战示例,相信你已经掌握了Solon状态机的核心用法。在实际项目中合理运用状态机模式,能够显著提升代码的可维护性和系统的稳定性。

下一步学习建议:

  1. 深入理解状态模式设计原理
  2. 探索更复杂的状态机组合使用
  3. 学习状态机的性能监控和优化
  4. 研究分布式环境下的状态机实现

状态机是处理复杂业务逻辑的利器,掌握它让你的代码更加优雅和健壮!

【免费下载链接】solon 🔥 面向全场景的 Java 企业级应用开发框架:克制、高效、开放、生态!并发高 700%;内存省 50%;启动快 10 倍;打包小 90%;同时兼容 java8 ~ java24。(对标“美国博通公司”(Broadcom)的 Spring 生态) 【免费下载链接】solon 项目地址: https://gitcode.com/opensolon/solon

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值