1.案例說明
- 該源碼為實際項目的脫敏版本,改造過程中,部分功能無法重現。由於售后涉及到訂單服務,用戶服務等這種跨系統的交互,在案例中基於防腐層做模擬實現。
- 案例的主要目是展示DDD應用傳統項目的流程,具體實現功能的代碼不是重點關注的對象,讀者可主要了解業務流程,業務規則在分層目錄中的實現。切不可對流程中的細節功能做過多分析。
- 構建實體與需求文檔相對應,構建實體的合理性不在本例中過多討論,本例前提是已經確定實體,聚合根后,具體編碼落地的細節展示。
- 源碼中所有實體(包括聚合根)均繼承BaseEntity,實體的唯一主鍵均繼承自BaseID。BaseEntity,BaseID是一個只包括uuid的基礎值對像。
- 源碼中所有的倉庫層均繼承BaseRepository接口,便於統一定義倉庫的通用操作,如實體的保存,查詢,移除(設置基礎對象,基礎接口,有助於統一管理實體和擴展實體的功能)。參考代碼如下:

/** * 基礎倉庫接口 * 倉庫的一些通用操作 * * @author wl * @date 2021-9-27 */ public interface BaseRepository<T extends BaseEntity, ID extends BaseID> { /** * 保存實體 * * @param t 實體 * @return 數據字典 */ default T save(T t) { return t; } /** * 查詢實體 * * @param keyId 查詢主鍵 * @return 返回實體 */ default T find(ID keyId) { return null; } /** * 刪除實體 * * @param keyId 查詢主鍵 */ default void remove(ID keyId) { } }
2.案例啟動
- 本例采用SpringBoot構建一個微服務,依賴請參考pom.xml文件。
- 本例使用了數據庫(mysql),相關的數據腳本,請在資源文件中查看,路徑為:resources/static/demosql。
- 先在本地或服務器上面構建好數據庫,導入數據表腳本。
- 修改application.properties,數據庫的連接地址請修改為本地可連接的配置地址。
- 啟動或調試DDDApplication.java,項目啟動成功后,才可以測試整個流程。啟動成功如圖:
3.案例測試
- 本例所用的訂單信息,是虛擬設置的一個(在源碼中可修改訂單信息)。且只能基於這個訂單號做售后補償業務測試。
- 為了便於理解,請查看com.wangling.base.tool.ddd.compensate.CompensateControllerTest.java文件,作者編寫了測試用例,讀者可基於測試用例一步一步的測試或查看代碼。
- 創建補償單過程源碼參考:
@Override public long save(CompensateApplyCommand compensateApplyCommand) { // 應用層體現 業務流程: // 獲取訂單信息-基於防腐層獲取 OrderV orderV = compensateSelectFacade.getOrderResponse(compensateApplyCommand.getCompensateBillCommand().getSubOid()); // 獲取人員信息-基於防腐層獲取 UserResponse userResponse = compensateSelectFacade.getUserResponse(compensateApplyCommand.getCompensateBillCommand().getActuid()); // 基於工廠創建實體 CompensateBillA compensateBillA = compensateBillFactory.createCompensateBillA(compensateApplyCommand, orderV, userResponse); // 調用領域層處理保存的業務邏輯 CompensateBillA compensateBillAdd = compensateBillA.process(compensateBillDomainService); // 調用倉庫保存數據 compensateBillRepository.save(compensateBillAdd); // 保存完成后,消息通知其他系統 sendCreateMessage(compensateBillAdd); // 保存完成后,主動發起審核 long coid = compensateBillAdd.getCompensateBillId().getCoid(); check(CheckTypeEnum.AUTO_CHECK, coid, compensateBillAdd.getActuid()); return coid; }