美文网首页-今晚吃啥子? -罗非鱼。
Java使用更优雅的代码记录数据的变更日志

Java使用更优雅的代码记录数据的变更日志

作者: 水煮鱼又失败了 | 来源:发表于2021-06-09 12:37 被阅读0次

    1 场景

    系统中经常会记录数据的更改日志,记录数据的变更前的内容变更后的内容。而且有时候会记录数据的多个字段的变更前和变更后的内容(如状态的变更前后、用户的变更前后、金额的变更前后,而且有的内容不发生变更的时候,不需要进行记录)。

    如果现在有个日志记录类,如下:

    @Data
    public class RecordChangeLog {
        
        /**
         * 操作
         */
        private String operate;
        
        /**
         * 操作人
         */
        private String operateUser;
        
        /**
         * 操作时间
         */
        private Long operateTime;
        
        /**
         * “状态”变更前
         */
        private String statusBefore;
        
        /**
         * ”状态“变更后
         */
        private String statusAfter;
        
        /**
         * "金额"变更前
         */
        private BigDecimal moneyBefore;
        
        /**
         * "金额"更能后
         */
        private BigDecimal moneyAfter;
        
    }
    

    此种需求经常的实现方式是:

    RecordChangeLog recordChangeLog = new RecordChangeLog();
    recordChangeLog.setOperate("xxx操作");
    recordChangeLog.setOperateUser("张三");
    recordChangeLog.setOperateTime(System.currentTimeMillis());
    // 如果“状态Status”变更了,则记录
    recordChangeLog.setStatusBefore("变更前状态");
    recordChangeLog.setStatusBefore("变更后状态");
    // 如果“金额Money”变更了,则记录
    recordChangeLog.setMoneyBefore(new BigDecimal(100));
    recordChangeLog.setMoneyAfter(new BigDecimal(200));
    

    此种方式,缺点如下:

    • 写set方法设置参数的时候,容易漏掉,或者写错调用的set方法,导致日志记录的错误。
    • 代码冗余量太大,如果日志记录的属性较多时,封装成通用方法也较为复杂
    • 代码不明确,无法明确此次记录到底需要更改记录哪些属性。

    2 代码实现

    下面将使用更优化的代码实现日志变更记录。

    /**
     * 日志包装器
     */
    public class RecordChangeLogWrapper {
        /**
         * 日志实体类
         */
        private RecordChangeLog recordChangeLog;
        
        /**
         * 构造函数
         * @param operate     操作类型(可用枚举类替代)
         * @param operateUser 操作人
         */
        public RecordChangeLogWrapper(String operate, String operateUser) {
            if (StringUtils.isEmpty(operate) || StringUtils.isEmpty(operateUser)) {
                throw new IllegalArgumentException("operate or operateUser is null");
            }
            recordChangeLog = new RecordChangeLog();
            recordChangeLog.setOperate(operate);
            recordChangeLog.setOperateUser(operateUser);
            recordChangeLog.setOperateTime(System.currentTimeMillis());
        }
        
        /**
         * 获取实例
         * @return
         */
        public RecordChangeLog getInstance(){
            return this.recordChangeLog;
        }
        
        /**
         * 变更“状态”
         * @param statusBefore “状态”变更前
         * @param statusAfter  “状态”变更后
         * @return
         */
        public RecordChangeLogWrapper changeStatus(String statusBefore, String statusAfter) {
            this.recordChangeLog.setStatusBefore(statusBefore);
            this.recordChangeLog.setStatusAfter(statusAfter);
            return this;
        }
        
        /**
         * 变更“金额”
         * @param moneyBefore "金额"变更前
         * @param moneyAfter  "金额"变更后
         * @return
         */
        public RecordChangeLogWrapper changeMoney(BigDecimal moneyBefore, BigDecimal moneyAfter) {
            this.recordChangeLog.setMoneyBefore(moneyBefore);
            this.recordChangeLog.setMoneyAfter(moneyAfter);
            return this;
        }
    }
    

    使用方式如下:

    // 更改状态和金额
    RecordChangeLogWrapper recordChangeLogWrapper1 = new RecordChangeLogWrapper("xx操作", "张三").changeStatus("待审核", "审核通过").changeMoney(new BigDecimal(100), new BigDecimal(200));
    RecordChangeLog recordChangeLog1 = recordChangeLogWrapper1.getInstance();
    
    // 更改状态
    RecordChangeLogWrapper recordChangeLogWrapper2 = new RecordChangeLogWrapper("xx操作", "张三").changeStatus("待审核", "审核通过");
    RecordChangeLog recordChangeLog2 = recordChangeLogWrapper2.getInstance();
    
    // 更改金额
    RecordChangeLogWrapper recordChangeLogWrapper3 = new RecordChangeLogWrapper("xx操作", "张三").changeMoney(new BigDecimal(100), new BigDecimal(200));
    RecordChangeLog recordChangeLog3 = recordChangeLogWrapper3.getInstance();
    

    相关文章

      网友评论

        本文标题:Java使用更优雅的代码记录数据的变更日志

        本文链接:https://www.haomeiwen.com/subject/hjnjeltx.html