美文网首页-今晚吃啥子? -罗非鱼。
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