buguge - Keep it simple,stupid

知识就是力量,但更重要的,是运用知识的能力why buguge?

导航

系统熵增是怎么产生的?————数据对象模型里添加属性欠思考

熵增定律指出,在没有外力作用下的封闭系统中,熵(或混乱度)总是增加的。就是说,任何封闭系统中、在没有外力作用下,都会陷入混乱。

屋子不收拾会变乱;人不自律会懒散;生活不规律或无节制,人就会出现健康问题;同样,对于我们的信息系统,一旦缺乏规范和管控,就会越来越难于迭代和维护。

这些例子都展示了在缺乏积极干预的情况下,事物往往会趋向于混乱和无序。因此,对于个人和社会来说,重要的是意识到这种趋势,并积极采取适当的措施来对抗熵增,即具有熵减的能力,来维持秩序、管理事物并保持整体的稳定和有序。 

 

我们系统中调用通道查询订单支付结果的逻辑,我结合伪代码表示如下。

public void queryOrderPayResult(orderNo){
    ...
    // 从数据库里取出来的订单数据记录
    Order entity = orderMapper.selectById(orderNo);
    // 订单当前支付状态已经是终态,终止
    if (isFinalState(entity.getPayStatus()) return;
    ...
    OrderVO orderVO = BeanMapper.map(entity, OrderVO.class);
    
    调用下游通道,执行查单逻辑
    
    orderVO.setPrevPayStatus(orderVO.getPayStatus());
    if (查单返回支付成功) {
        orderVO.setPayStatus(SUCCESS);
        orderVO.setCompleteTime(xxx);
    } else(查单返回支付失败) {
        orderVO.setPayStatus(FAIL);
    } else{
        // 查单返回支付中,无操作,直接return
        return;
    }
    updatePayQueryResult(orderVO);
}

private void updatePayQueryResult(OrderVO orderVO){
    Order updateEntity = new Order()
        .setPayStatus(orderVO.getPayStatus())
        .setCompleteTime(orderVO.getCompleteTime())
        .setUpdateTime(new Date());
    
    LambdaQueryWrapper<Order> updateWrapper = new LambdaQueryWrapper<Order>()
        .eq(Order::getOrderNo, orderVO.getOrderNo())
        .eq(Order::getOrderStatus, OrderVO.getPrevPayStatus());
    // 持久化更新支付状态
    orderMapper.update(OrderUpdate, updateWrapper);
}

其中,Order代表订单数据实体,OrderVO是Order的值对象表示形式,在程序方法及交互中使用。订单对象包含有 订单号orderNo、支付状态payStatus、完成时间completeTime 等属性,OrderVO也定义对应的属性。

这里要说的是OrderVO的prevPayStatus属性。prevPayStatus,见名知意,表示“前一个支付状态”。上面这段代码中,为了在更新订单的支付状态时使用状态锁,而在OrderVO上定义了 prevPayStatus 属性。我们系统中对订单的操作逻辑较多,为了满足相关操作在这个OrderVO中也定义了诸如 createTimeBegin、createTimeEnd、prevVerifyStatus等属性。这种程序设计,我认为,就产生了系统熵增。如果不加以约束和控制,OrderVO在日后迭代中会有更多类似属性。

消除熵增的办法就是将这些属性从OrderVO中去掉,保持OrderVO的干净整洁。

 

那么,基于示例中的场景,我们如何去掉 OrderVO#prevPayStatus 呢?

更新订单支付状态,尤其要注意状态机控制。假定支付状态流转为 待支付INIT→支付中PAYING→支付成功SUCCESS/支付失败FAIL。那么一笔交易,在更新为支付终态(SUCCESS/FAIL)时,前提条件一定是PAYING。

因此,我们完全可以去掉 prevPayStatus 属性。queryOrderPayResult方法中,去掉 prevPayStatus的赋值;updatePayQueryResult方法中, updateWrapper直接设置orderStatus为PAYING。

 

posted on 2023-09-09 23:20  buguge  阅读(67)  评论(0编辑  收藏  举报