如何避免寫出爛的業務代碼(2)- 領域對象與領域服務

問題

  1. 什麼是領域對象

  2. 什麼是領域服務

  3. 領域對象的行爲,與領域服務的行爲區別

原因

定義

領域對象: 聚合根,實體,值對象 領域的數據與行爲, 數據和行爲應該與業務產品上的行爲關聯。領域對象通常是有狀態的,理想情況下,我們的領域對象行爲應該和產品業務定義意義映射

觀點

首先需要對概念明確定義,因爲 DDD 其實是做了一個問題的分治,所以必然會導致在某些情況下,會有單薄這個說法。就像垂直架構中 dao/manager/service 層區分一樣。在初期我們可以明確按照概念來放置代碼,當大家達成共識,深刻理解了這些概念時,沒有其中一層也無所謂了。

舉個例子 eg. 一個 bad case 三個模型:A,B,C, 他們之間存在狀態變更流動。

整理出來的狀態變更圖 AService.updateXXStatus

AService.cancelBy

AService.changeStatus()

這些方法都在處理狀態,反應不了業務的情況

領域對象:

一般包含以下邏輯

  1. publicRoulettePrize executeRoulette(finalList<RoulettePrize> prizes,

  2. finalInteger dailyFreeRouletteCount,

  3. finalint rouletteCountToday,finalUserDTO userDTO)throwsBizzException{

  4. finalList<RoulettePrize> validPrize = prizes.stream().filter(p -> checkPrizeValid(p))

  5. // 排除掉中獎概率不合法和概率爲0的獎品

  6. .filter(p ->ArithUtil.checkIntegerRange(p.getRate(),0,Integer.MAX_VALUE))

  7. // 校驗中獎次數限制

  8. .filter(p -> checkPrizeLimit(p))

  9. // 校驗vip獎品限制

  10. .filter(p -> checkPrizeVip(p, userDTO))

  11. .filter(p -> checkFreePrize(p,dailyFreeRouletteCount, rouletteCountToday)).collect(

  12. Collectors.toList());

  13. finalint totalRate = validPrize.stream().mapToInt(p -> p.getRate()).sum();

  14. // 排除無效獎品,計算有效獎品概率之和

  15. if(CollectionUtils.isEmpty(validPrize)){

  16. throwRouletteResponseCode.convertBizzException(RouletteResponseCode.PRIZE_EMPTY);

  17. }

  18. return chooseResultPrize(validPrize, totalRate ==0?1: totalRate);

  19. }

不應該做的事

領域對象不應該與其他的模型有交互,如 manager(資源層管理),不應該持久化數據 如何持久化不應該是領域對象關心的。

領域服務

領域服務與領域對象的關係

領域服務通常是領域對象的調用方,是微服務架構下,領域對象對外提供的方式。

AService

1   // 構建領域對象
2    final List<AAggr> aggr = mAManager.listByUserIds(userVal);
3    final AEntity entity = CollectionUtils.isEmpty(aggr) ? null : aggr.get(0)
4            .getA();    
5   // 調用領域對象方法
6    entity.checkDesignerExist();
7    entity.checkUpdate();
8
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s?__biz=MzI4NjI3MDc1NA==&amp;mid=2247483800&amp;idx=1&amp;sn=ca57d8b7e44229daecdd3a7103eabca6&amp;chksm=ebde35d5dca9bcc3c828e410dcc6629e3f02b5c46007e2358c7ec905a79115c35faeddbc9dae&amp;scene=21#wechat_redirect