场景1
系统中经常会记录数据的更改日志,记录数据的变更前的内容和变更后的内容。而且有时候会记录数据的多个字段的变更前和变更后的内容(如状态的变更前后、用户的变更前后、金额的变更前后,而且有的内容不发生变更的时候,不需要进行记录)。
现在有日志记录实体类如下:
package com.wangcp.changelog.entity;
import lombok.Data;
import java.math.BigDecimal;
/**
* 日志记录实体
*
* @author wangcp
* <br/>date 2021-06-24
*/
@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 代码实现
下面优化原代码,对日志实体类进行包装实现。
package com.wangcp.changelog.config;
import com.wangcp.changelog.entity.RecordChangeLog;
import org.apache.commons.lang3.StringUtils;
import java.math.BigDecimal;
/**
* 日志包装器
*
* @author wangcp
* <br/>date 2021-06-24
*/
public class RecordChangeLogWrapper {
private RecordChangeLog recordChangeLog;
/**
* 构造函数
* @param operate 操作类型(可用枚举代替)
* @param opearteUser 操作人
* @return
* @author wangcp
* <br/>date 2021-06-24
*/
public RecordChangeLogWrapper(String operate , String opearteUser) {
if(StringUtils.isEmpty(operate) || StringUtils.isEmpty(opearteUser)){
throw new IllegalArgumentException("operate or opearteUser is null");
}
recordChangeLog = new RecordChangeLog();
recordChangeLog.setOperate(operate);
recordChangeLog.setOperateUser(opearteUser);
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;
}
}
使用方式如下:
/**
* 调用包装类初始化日志数据
*/
public void testNewLog(){
// 更改状态与金额
RecordChangeLogWrapper recordChangeLogWrapper1 = new RecordChangeLogWrapper("新增操作" , "张三")
.changeMoney(new BigDecimal(100) , new BigDecimal(200))
.changeStatus("待审核" , "审核通过");
RecordChangeLog recordChangeLog1 = recordChangeLogWrapper1.getInstance();
// 更改状态
RecordChangeLogWrapper recordChangeLogWrapper2 = new RecordChangeLogWrapper("修改操作" , "李四")
.changeStatus("待审核" , "驳回");
RecordChangeLog recordChangeLog2 = recordChangeLogWrapper2.getInstance();
// 更改金额
RecordChangeLogWrapper recordChangeLogWrapper3 = new RecordChangeLogWrapper("删除操作" , "王大")
.changeMoney(new BigDecimal(200) , new BigDecimal(500));
RecordChangeLog recordChangeLog3 = recordChangeLogWrapper3.getInstance();
}