Java使用更優(yōu)雅的代碼記錄數(shù)據(jù)的變更日志

1 場(chǎng)景

系統(tǒng)中經(jīng)常會(huì)記錄數(shù)據(jù)的更改日志,記錄數(shù)據(jù)的變更前的內(nèi)容變更后的內(nèi)容。而且有時(shí)候會(huì)記錄數(shù)據(jù)的多個(gè)字段的變更前和變更后的內(nèi)容(如狀態(tài)的變更前后、用戶(hù)的變更前后、金額的變更前后,而且有的內(nèi)容不發(fā)生變更的時(shí)候,不需要進(jìn)行記錄)。

如果現(xiàn)在有個(gè)日志記錄類(lèi),如下:

@Data
public class RecordChangeLog {
    
    /**
     * 操作
     */
    private String operate;
    
    /**
     * 操作人
     */
    private String operateUser;
    
    /**
     * 操作時(shí)間
     */
    private Long operateTime;
    
    /**
     * “狀態(tài)”變更前
     */
    private String statusBefore;
    
    /**
     * ”狀態(tài)“變更后
     */
    private String statusAfter;
    
    /**
     * "金額"變更前
     */
    private BigDecimal moneyBefore;
    
    /**
     * "金額"更能后
     */
    private BigDecimal moneyAfter;
    
}

此種需求經(jīng)常的實(shí)現(xiàn)方式是:

RecordChangeLog recordChangeLog = new RecordChangeLog();
recordChangeLog.setOperate("xxx操作");
recordChangeLog.setOperateUser("張三");
recordChangeLog.setOperateTime(System.currentTimeMillis());
// 如果“狀態(tài)Status”變更了,則記錄
recordChangeLog.setStatusBefore("變更前狀態(tài)");
recordChangeLog.setStatusBefore("變更后狀態(tài)");
// 如果“金額Money”變更了,則記錄
recordChangeLog.setMoneyBefore(new BigDecimal(100));
recordChangeLog.setMoneyAfter(new BigDecimal(200));

此種方式,缺點(diǎn)如下:

  • 寫(xiě)set方法設(shè)置參數(shù)的時(shí)候,容易漏掉,或者寫(xiě)錯(cuò)調(diào)用的set方法,導(dǎo)致日志記錄的錯(cuò)誤。
  • 代碼冗余量太大,如果日志記錄的屬性較多時(shí),封裝成通用方法也較為復(fù)雜
  • 代碼不明確,無(wú)法明確此次記錄到底需要更改記錄哪些屬性。

2 代碼實(shí)現(xiàn)

下面將使用更優(yōu)化的代碼實(shí)現(xiàn)日志變更記錄。

/**
 * 日志包裝器
 */
public class RecordChangeLogWrapper {
    /**
     * 日志實(shí)體類(lèi)
     */
    private RecordChangeLog recordChangeLog;
    
    /**
     * 構(gòu)造函數(shù)
     * @param operate     操作類(lèi)型(可用枚舉類(lèi)替代)
     * @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());
    }
    
    /**
     * 獲取實(shí)例
     * @return
     */
    public RecordChangeLog getInstance(){
        return this.recordChangeLog;
    }
    
    /**
     * 變更“狀態(tài)”
     * @param statusBefore “狀態(tài)”變更前
     * @param statusAfter  “狀態(tài)”變更后
     * @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;
    }
}

使用方式如下:

// 更改狀態(tài)和金額
RecordChangeLogWrapper recordChangeLogWrapper1 = new RecordChangeLogWrapper("xx操作", "張三").changeStatus("待審核", "審核通過(guò)").changeMoney(new BigDecimal(100), new BigDecimal(200));
RecordChangeLog recordChangeLog1 = recordChangeLogWrapper1.getInstance();

// 更改狀態(tài)
RecordChangeLogWrapper recordChangeLogWrapper2 = new RecordChangeLogWrapper("xx操作", "張三").changeStatus("待審核", "審核通過(guò)");
RecordChangeLog recordChangeLog2 = recordChangeLogWrapper2.getInstance();

// 更改金額
RecordChangeLogWrapper recordChangeLogWrapper3 = new RecordChangeLogWrapper("xx操作", "張三").changeMoney(new BigDecimal(100), new BigDecimal(200));
RecordChangeLog recordChangeLog3 = recordChangeLogWrapper3.getInstance();
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請(qǐng)通過(guò)簡(jiǎn)信或評(píng)論聯(lián)系作者。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容