DDD及相关概念
?
- 領(lǐng)域:指一個(gè)具體的應(yīng)用范圍,比如電商、訂票管理、會(huì)議管理等,實(shí)現(xiàn)某一領(lǐng)域的功能,與其對(duì)應(yīng)的商業(yè)領(lǐng)域一致。譬如Contoso會(huì)議管理系統(tǒng)從兩個(gè)方面來闡述(1)系統(tǒng)概覽:銷售會(huì)議座位、創(chuàng)建新會(huì)議【領(lǐng)域的活動(dòng)是什么,核心內(nèi)容】(2)非功能性需求:擴(kuò)展性、靈活性【降低維護(hù)成本,延長(zhǎng)生命周期】。
- 有界上下文:引入本概念的目的是為大型、復(fù)雜系統(tǒng)的分解提供一種容易管理的方法。在這種分解方式下,一個(gè)大型系統(tǒng)由多個(gè)有界上下文構(gòu)成,每個(gè)有界上下文所包含的是一個(gè)自包容的領(lǐng)域模型,且有自己本身的普適語言。可以將有界上下文看做是一個(gè)有著清晰一致性邊界的自動(dòng)化的商業(yè)組件。在通常情況下,一個(gè)有界上下文更另一個(gè)有界上下文進(jìn)行通信的方法是發(fā)送事件。
- 上下文線路圖:描述不同模型之間的接觸點(diǎn),明確說明所有需要進(jìn)行翻譯的通信鏈接,并注明任何共享模塊或?qū)ο蟆S脩粼谶M(jìn)行這些活動(dòng)后得出的結(jié)果就是一種“上下文線路圖”。這種地圖提供的是整個(gè)系統(tǒng)的概覽,幫忙人民理解不同的有界上下文是如何相互交互的。
- 失血模型:模型僅僅包含數(shù)據(jù)的定義和getter/setter方法,業(yè)務(wù)邏輯和應(yīng)用邏輯都放到服務(wù)層中。這種類在java中叫POJO,在.NET中叫POCO。
- 貧血模型:貧血模型中包含了一些業(yè)務(wù)邏輯,但不包含依賴持久層的業(yè)務(wù)邏輯。這部分依賴于持久層的業(yè)務(wù)邏輯將會(huì)放到服務(wù)層中。可以看出,貧血模型中的領(lǐng)域?qū)ο笫遣灰蕾囉诔志脤拥摹?
- 充血模型:充血模型中包含了所有的業(yè)務(wù)邏輯,包括依賴于持久層的業(yè)務(wù)邏輯。所以,使用充血模型的領(lǐng)域?qū)邮且蕾囉诔志脤?#xff0c;簡(jiǎn)單表示就是 UI層->服務(wù)層->領(lǐng)域?qū)?lt;->持久層
- 脹血模型:脹血模型就是把和業(yè)務(wù)邏輯不想關(guān)的其他應(yīng)用邏輯(如授權(quán)、事務(wù)等)都放到領(lǐng)域模型中。我感覺脹血模型反而是另外一種的失血模型,因?yàn)榉?wù)層消失了,領(lǐng)域?qū)痈闪朔?wù)層的事,到頭來還是什么都沒變。
- 實(shí)體:
- 值對(duì)象:
- 聚合:
- 上下文:
- 函數(shù)式編程:
- 函數(shù)式編程三大思想:
immutable data 不可變數(shù)據(jù):像Clojure一樣,默認(rèn)上變量是不可變的,如果你要改變變量,你需要把變量copy出去修改。這樣一來,可以讓你的程序少很多Bug。因?yàn)?#xff0c;程序中的狀態(tài)不好維護(hù),在并發(fā)的時(shí)候更不好維護(hù)。(你可以試想一下如果你的程序有個(gè)復(fù)雜的狀態(tài),當(dāng)以后別人改你代碼的時(shí)候,是很容易出bug的,在并行中這樣的問題就更多了)
first class functions:這個(gè)技術(shù)可以讓你的函數(shù)就像變量一樣來使用。也就是說,你的函數(shù)可以像變量一樣被創(chuàng)建,修改,并當(dāng)成變量一樣傳遞,返回或是在函數(shù)中嵌套函數(shù)。這個(gè)有點(diǎn)像Javascript的Prototype。
尾遞歸優(yōu)化:我們知道遞歸的害處,那就是如果遞歸很深的話,stack受不了,并會(huì)導(dǎo)致性能大幅度下降。所以,我們使用尾遞歸優(yōu)化技術(shù)——每次遞歸時(shí)都會(huì)重用stack,這樣一來能夠提升性能,當(dāng)然,這需要語言或編譯器的支持。Python就不支持。
- 函數(shù)式編程的技術(shù):
map & reduce :這個(gè)技術(shù)不用多說了,函數(shù)式編程最常見的技術(shù)就是對(duì)一個(gè)集合做Map和Reduce操作。這比起過程式的語言來說,在代碼上要更容易閱讀。(傳統(tǒng)過程式的語言需要使用for/while循環(huán),然后在各種變量中把數(shù)據(jù)倒過來倒過去的)這個(gè)很像C++中的STL中的foreach,find_if,count_if之流的函數(shù)的玩法。
pipeline:這個(gè)技術(shù)的意思是,把函數(shù)實(shí)例成一個(gè)一個(gè)的action,然后,把一組action放到一個(gè)數(shù)組或是列表中,然后把數(shù)據(jù)傳給這個(gè)action list,數(shù)據(jù)就像一個(gè)pipeline一樣順序地被各個(gè)函數(shù)所操作,最終得到我們想要的結(jié)果。
recursing 遞歸 :遞歸最大的好處就簡(jiǎn)化代碼,他可以把一個(gè)復(fù)雜的問題用很簡(jiǎn)單的代碼描述出來。注意:遞歸的精髓是描述問題,而這正是函數(shù)式編程的精髓。
currying:把一個(gè)函數(shù)的多個(gè)參數(shù)分解成多個(gè)函數(shù), 然后把函數(shù)多層封裝起來,每層函數(shù)都返回一個(gè)函數(shù)去接收下一個(gè)參數(shù)這樣,可以簡(jiǎn)化函數(shù)的多個(gè)參數(shù)。在C++中,這個(gè)很像STL中的bind_1st或是bind2nd。
higher order function 高階函數(shù):所謂高階函數(shù)就是函數(shù)當(dāng)參數(shù),把傳入的函數(shù)做一個(gè)封裝,然后返回這個(gè)封裝函數(shù)。現(xiàn)象上就是函數(shù)傳進(jìn)傳出,就像面向?qū)ο髮?duì)象滿天飛一樣。
- Event Source: 事件源
基于事件源解決方案的核心要素是:
(1)在aggregate實(shí)例的狀態(tài)發(fā)生變化時(shí),該實(shí)例將發(fā)起一個(gè)事件來完整描述此種狀態(tài)變化。
(2)系統(tǒng)將這些發(fā)生事件保存在一個(gè)事件庫(kù)里面。
(3)aggregate可以通過重播過去的事件流來重建自己的狀態(tài)。[在對(duì)系統(tǒng)的錯(cuò)誤進(jìn)行分析時(shí),事件源和事件重播真是無價(jià)的。例如,我們可以首先在本地復(fù)制一個(gè)事件庫(kù),然后在本地重播事件流來對(duì)應(yīng)用程序進(jìn)行調(diào)試,并理解到底在生產(chǎn)系統(tǒng)里面發(fā)生了什么事情。]
(4)其他aggregate和流程管理器(可能位于不同的有界上下文里)可以訂購(gòu)這些事件。
- CQRS: Command Query Responsibility Segregation 命令查詢職責(zé)分離模式
- 自洽:自洽是操作的一種特性,意味著該操作能夠應(yīng)用多次而不改變結(jié)果。例如,“將變量x的值設(shè)置為10”就是一個(gè)自洽操作,而“在x的值上面加1”則不是自洽操作。在消息傳遞環(huán)境中,如果一條消息可以傳遞多次而不會(huì)改變結(jié)果,則該消息是自洽的。消息自洽的原因有兩個(gè):有可能是消息本身的性質(zhì)使然,也有可能是系統(tǒng)處理消息的方法使然。【來自:探索CQRS和事件源.pdf 第137頁(yè)】
?
總結(jié)
- 上一篇: JavaScript模块化开发整理
- 下一篇: 搜索引擎solr和elasticsear