领域驱动设计-从贫血模型到充血模型
背景
領(lǐng)域模型對象只是用來存儲(chǔ)應(yīng)用的數(shù)據(jù)。業(yè)務(wù)邏輯位于服務(wù)層中,管理域?qū)ο蟮臄?shù)據(jù)。在服務(wù)層中,應(yīng)用的每個(gè)實(shí)體對應(yīng)一個(gè)服務(wù)類。這種模式大家是不是很熟悉,尤其是在中小項(xiàng)目或者項(xiàng)目剛啟動(dòng)的時(shí)候,都是怎么方便怎么來;沒錯(cuò),這就是貧血模型。
一般畫風(fēng)是這樣的。
1、Web層:接收用戶輸入,將數(shù)據(jù)傳至服務(wù)層;
2、服務(wù)層:處理業(yè)務(wù)邏輯、權(quán)限管理與授權(quán),并與存儲(chǔ)層通信;
using BQoolCommon.Interface.Repository.Dapper; using BQoolCommon.Interface.Service; using BQoolCommon.Models.BQoolCommon_SetMain; using BQoolCommon.Models.Enum; using BQoolCommon.Models.ViewModel; using System; using System.Collections.Generic; using System.Configuration;namespace BQoolCommon.Service {public class UserPermissionService : IUserPermissionService{private readonly IInnerSiteMapDapperRep _innerSiteMapDapperRep;private readonly IInnerSiteMapService _innerSiteMapService;private readonly IAccountChannelRelService _accountChannelRelService;private readonly IUserMgmtService _userMgmtService;public UserPermissionService(IInnerSiteMapDapperRep innerSiteMapDapperRep,IInnerSiteMapService innerSiteMapService, IAccountChannelRelService accountChannelRelService, IUserMgmtService userMgmtService){_innerSiteMapDapperRep = innerSiteMapDapperRep;_innerSiteMapService = innerSiteMapService;_accountChannelRelService = accountChannelRelService;_userMgmtService = userMgmtService;} .................................................3、存儲(chǔ)層:與數(shù)據(jù)庫進(jìn)行通信,對數(shù)據(jù)進(jìn)行持久化;
using System.Linq; using BQoolCommon.Interface.Factory; using BQoolCommon.Interface.Repository.Entity; using BQoolCommon.Models.BQoolCommon_SetMain; using BQoolCommon.Models.ViewModel;namespace BQoolCommon.Repository.Entity {public class WeChatSubscribeEntityRep : GenericEntityRep<WeChat_Subscribe>, IWeChatSubscribeEntityRep{public WeChatSubscribeEntityRep(IBqoolSetMainDbContextFactory factory) : base(factory){}} }問題窺探
問題出在了服務(wù)層,他承受了太多的職責(zé),像業(yè)務(wù)邏輯、權(quán)限檢查等等,這違反了單一職責(zé)原則,并產(chǎn)生了大量的依賴。當(dāng)業(yè)務(wù)復(fù)雜度上升時(shí),服務(wù)層所包含的代碼將會(huì)非常龐大和復(fù)雜。服務(wù)層需要包含應(yīng)用邏輯、用戶會(huì)話的管理;領(lǐng)域?qū)討?yīng)該包含業(yè)務(wù)邏輯,可以處理與業(yè)務(wù)相關(guān)的會(huì)話狀態(tài)。
改進(jìn)思路
我們需要將業(yè)務(wù)邏輯從服務(wù)層移動(dòng)到領(lǐng)域模型中,這樣的好處是,服務(wù)層可以只負(fù)責(zé)應(yīng)用邏輯(如數(shù)據(jù)有效性驗(yàn)證、授權(quán)檢查、開始結(jié)束事務(wù)等),領(lǐng)域模型可以專門負(fù)責(zé)其相關(guān)的業(yè)務(wù)邏輯。以電商系統(tǒng)來舉例,架構(gòu)設(shè)計(jì)時(shí)完全可以針對訂單、商品、庫存等多個(gè)領(lǐng)域模型進(jìn)行建模,相關(guān)的業(yè)務(wù)可以分別放到不同的領(lǐng)域模型中,一些很有可能重復(fù)的業(yè)務(wù)代碼都會(huì)被集中到一處,從而降低了復(fù)制-粘貼的可能性,這就是充血模型。
影響
充血模型將服務(wù)類變得更小,使之只負(fù)責(zé)單一的職責(zé)。例如商品的CRUD和其他操作,就可以將其放到兩個(gè)不同的服務(wù)類中,一個(gè)負(fù)責(zé)商品的CRUD操作,另外一個(gè)負(fù)責(zé)與商品相關(guān)的其他操作。這樣就能使服務(wù)類變得小巧、松散、可測試了,同時(shí)還能降低其他人理解與重用的成本。
總結(jié)
1、從規(guī)范和長遠(yuǎn)來看肯定是充血模型合適些。
2、但是如果只是小項(xiàng)目、求快的話,當(dāng)然是開發(fā)成本低的貧血模型。
總結(jié)
以上是生活随笔為你收集整理的领域驱动设计-从贫血模型到充血模型的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在.NET Core 中实现健康检查
- 下一篇: 读书 | IT人如何直击本质洞察底层逻辑