版本 | 日期 | 備注 |
---|---|---|
1.0 | 2021.8.22 | 文章首發(fā) |
1.1 | 2021.8.26 | 增加對(duì)于核心思想的描述 |
之前的DDD文章——談?wù)劥a:降低復(fù)雜度,從放棄三層架構(gòu)到DDD入門
丈冬,通篇下來(lái)像 是簡(jiǎn)單的講了一些概念嘱函,然后快速的實(shí)戰(zhàn)一下——很多同學(xué)反饋感覺(jué)就是入門了,但沒(méi)有完全入門埂蕊,因此我們?cè)偌右黄?/p>
1.什么是DDD
先看下萬(wàn)能的維基百科:Domain-driven design (DDD) is the concept that the structure and language of software code (class names, class methods, class variables) should match the business domain. For example, if a software processes loan applications, it might have classes such as LoanApplication and Customer, and methods such as AcceptOffer and Withdraw.
這邊將其稱為了一個(gè)概念往弓。在我看來(lái)DDD是設(shè)計(jì)模式的超集,一種指導(dǎo)思想——用來(lái)指導(dǎo)如何解耦業(yè)務(wù)系統(tǒng)蓄氧,劃分業(yè)務(wù)模塊函似,定義業(yè)務(wù)領(lǐng)域模型及其交互。
2. DDD誕生的背景
領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)這個(gè)概念并不新穎喉童,早在 2004 年就被提出了撇寞,到現(xiàn)在已經(jīng)有十幾年的歷史了。不過(guò)堂氯,它被大眾熟知重抖,還是基于另一個(gè)概念的興起,那就是微服務(wù)祖灰。因此在實(shí)現(xiàn)的時(shí)候樣子不一定是一模一樣的钟沛,更多時(shí)候還是根據(jù)業(yè)務(wù)場(chǎng)景來(lái)因材施教。
3. DDD的核心思想
核心思想是讓技術(shù)復(fù)雜度與業(yè)務(wù)復(fù)雜度隔離局扶,并通過(guò)統(tǒng)一語(yǔ)言組織業(yè)務(wù)邏輯恨统,降低認(rèn)知成本叁扫。
具體主要體現(xiàn)在:
- 基礎(chǔ)設(shè)施層:它負(fù)責(zé)隔離技術(shù)復(fù)雜度,通過(guò)抽象封裝來(lái)對(duì)內(nèi)提供服務(wù)畜埋,而不是讓內(nèi)部服務(wù)直接使用它莫绣。這意味著當(dāng)外部基礎(chǔ)設(shè)施變化時(shí),業(yè)務(wù)并不會(huì)被迫進(jìn)行變更悠鞍。比如項(xiàng)目中的數(shù)據(jù)總線是Kafka对室,之后替換成了Pulsar,業(yè)務(wù)對(duì)其應(yīng)該是無(wú)感知的咖祭。
- 厚領(lǐng)域?qū)樱和活I(lǐng)域的知識(shí)聚合在一個(gè)領(lǐng)域中掩宜,領(lǐng)域知識(shí)不再被割裂。這是單一職責(zé)原則的一種體現(xiàn)么翰。
- 實(shí)體:用充血模型代替貧血模型牺汤,完全符合面向?qū)ο蟮乃枷搿I(yè)務(wù)中的對(duì)象完全投射到實(shí)體中浩嫌,從面向資源轉(zhuǎn)換成面向過(guò)程和面向?qū)ο蟆?/li>
4. DDD能解決什么樣的問(wèn)題
一般軟件會(huì)經(jīng)歷幾個(gè)不同的周期:
- 大煙囪:每個(gè)應(yīng)用各自為政檐迟,類似的需求重復(fù)開發(fā),浪費(fèi)人力
- 服務(wù)化:根據(jù)不同的業(yè)務(wù)屬性拆分服務(wù)码耐。關(guān)注服務(wù)拆分追迟、服務(wù)治理、模型抽象
- 平臺(tái)化:將相關(guān)的微服務(wù)同一成一個(gè)平臺(tái)暴露出來(lái)骚腥。關(guān)注領(lǐng)域收斂怔匣、領(lǐng)域自治、能力沉淀
- 中臺(tái)化:將通用能力下沉至中臺(tái)桦沉,快速響應(yīng)前端服務(wù)。需要關(guān)注數(shù)據(jù)打通金闽、能力串聯(lián)纯露、業(yè)務(wù)響應(yīng)力
DDD主要在技術(shù)密集型應(yīng)用里有較大的作用,尤其是當(dāng)該應(yīng)用進(jìn)入服務(wù)化代芜、平臺(tái)化時(shí)埠褪,可以在:“服務(wù)拆分”、“服務(wù)治理”挤庇、“領(lǐng)域收斂”钞速、“領(lǐng)域自治”發(fā)揮。在中臺(tái)化中的“數(shù)據(jù)打通”也有一定的作用嫡秕。
而微觀來(lái)說(shuō)渴语,DDD可以有效減少代碼的冗余程度以及需求響應(yīng)的速度。
5. DDD實(shí)踐中要注意的
5.1 使用IOC來(lái)保證層次之間的隔離
經(jīng)常有小伙伴問(wèn)我昆咽,分層之間該怎么做驾凶?因?yàn)榉謱拥倪吔鐩](méi)做好牙甫,代碼會(huì)再度耦合再一起。對(duì)此我給出的答案是參考inversion of control
调违。其常見(jiàn)實(shí)現(xiàn)有:
- Object Dependency Inject
- Service Provider Interface
- Strategy
- Abstract Factory
也可以參考我之前寫的文章:技巧:遵循Clean Architecture寫好白盒測(cè)試窟哺。
5.2 模塊分離
模塊分離是一種較為“硬”的手段,它讓分層不再是一個(gè)約定技肩,而是強(qiáng)制執(zhí)行的規(guī)則且轨。這樣當(dāng)我們拆分微服務(wù)時(shí)候,也可以較快的完成拆分虚婿。
5.3 DDD并不是只有三層到四層
也有小伙伴問(wèn)過(guò)我旋奢,轉(zhuǎn)DDD的是否只有三層過(guò)來(lái)的?其實(shí)并非如此雳锋。我這邊可以舉兩個(gè)例子:
5.3.1 流計(jì)算處理
我們以面向在線數(shù)據(jù)加密應(yīng)用為例子:當(dāng)一條數(shù)據(jù)流過(guò)我們的應(yīng)用時(shí)黄绩,我們需要根據(jù)一些條件對(duì)其加密。
應(yīng)用的基本流程為:Source(from kafka) -> Map(encryption) -> Sink(to kafka)
玷过。
那么代碼中爽丹,kafka其實(shí)是基礎(chǔ)層的代碼。而encryption
屬于領(lǐng)域?qū)有廖茫琺ap(框架)和encryption之間的膠水代碼則屬于基礎(chǔ)層粤蝎。
5.3.2 GUI應(yīng)用
相信大家都在學(xué)生時(shí)代學(xué)過(guò)GUI or HTML 編程。那么按照DDD的做法來(lái)袋马,業(yè)務(wù)邏輯應(yīng)該與具體的界面無(wú)關(guān)——比如界面上的一個(gè)按鈕(數(shù)據(jù)模型)會(huì)觸發(fā)一種事件初澎,當(dāng)后臺(tái)的事件接受者收到這個(gè)事件時(shí),則會(huì)尋找相應(yīng)的執(zhí)行者虑凛,執(zhí)行對(duì)應(yīng)的邏輯碑宴。
在這里面:
- 界面可以是Qt,可以是Flex桑谍,可以是Ios延柠,可以是Android,也可以是Vue锣披。其本質(zhì)是用戶接口層贞间。
- 后臺(tái)的事件接受者是基礎(chǔ)層。
- 具體的執(zhí)行邏輯則放在領(lǐng)域?qū)印?/li>