本書是Eric Evans對他本身寫的《領域驅動設計-軟件核心複雜性應對之道》的一本字典式的參考書,可用於快速查找《領域驅動設計》中的諸多概念及其簡明解釋。html
其它本系列其它文章地址:算法
[譯文]Domain Driven Design Reference(一)—— 前言編程
[譯文]Domain Driven Design Reference(二)—— 讓模型起做用安全
[譯文]Domain Driven Design Reference(三)—— 模型驅動設計的構建模塊框架
[譯文]Domain Driven Design Reference(四)—— 柔性設計編程語言
要讓一個項目加速發展,而不是被其自身的歷史包袱所拖累,須要一個能與之良好協做的設計,它會帶來改變。一個柔性設計。函數
柔性設計是對深度建模的補充。單元測試
開發人員扮演兩種角色,每種角色都必須經過設計來完成。同一我的可能扮演這兩個角色,甚至能夠在幾分鐘內來回切換,但與代碼的關係卻不是這樣。一個角色是客戶端的開發人員,他們利用設計的方式將領域對象編織到應用程序代碼或其餘域層代碼中。柔性設計揭示了一個深層次的潛在模型,使其潛在性變得清晰。客戶端開發人員能夠靈活地使用一組最小松散耦合的概念來表示域中的一系列場景。設計元素以天然的方式融合在一塊兒,其結果是可預測的,清晰的特徵而且是健壯的。學習
一樣重要的是,設計必須服從於開發人員來改變它。要作出改變,設計必須易於理解,並能表達出客戶端開發人員正在使用的相同底層模型。它必須遵循該領域深層模型的概念,因此大多數變化都會在靈活點上柔性設計。其代碼的影響必須透明明顯,所以更改的後果將很容易預測。測試
• 使行爲特徵明顯
• 下降變動成本
• 建立與之合做的軟件開發人員
若是開發人員必須考慮組件的實現才能使用它,則封裝的價值就沒有了。若是原始開發人員之外的人必須根據其實現來推斷對象或操做的目的,新的開發者可能會推斷出一個意圖——操做或類只是偶然地執行。若是這不是意圖的話,那麼代碼可能暫時有效,但設計的概念基礎已經被破壞了,兩個開發人員將在交叉目的下工做。
所以:
命名類名和操做名來描述它們的效果和目的,而不用參考它們作出履約的方法。這減輕了客戶開發者理解內部的必要性。這些名字應符合通用語言,以便團隊成員能夠快速推斷其含義。在建立它以前爲行爲編寫一個測試,以強制您的思惟進入客戶端開發人員模式。
多個規則或計算的組合的相互做用變得很是難以預測。開發人員調用一個操做必須理解它的實現以及全部委託的實現,以便預測結果。若是開發人員被迫刺破遮罩層,任何抽象接口的用處都是有限的。若是沒有安全可預測的抽象,開發人員必須限制組合爆炸,對可行的豐富行爲設置較低的上限。
所以:
將盡量多的程序邏輯放入函數中,返回沒有明顯反作用的結果。嚴格地將命令(引發明顯的狀態改變的方法)分隔成不返回領域信息的很是簡單的操做。當發現了一個符合職責的概念時,經過將複雜的邏輯轉化爲值對象來進一步控制反作用。
值對象的全部操做都應該是無反作用的函數。
當操做的反作用只是經過實現而隱含地定義時,大量委託的設計就會成爲一種混亂的因果關係。理解程序的惟一方法是經過分支路徑來跟蹤執行。封裝的價值失去了。跟蹤具體執行的必要性使抽象也失敗了。
所以:
狀態操做的後置條件以及類和聚合的不變性。若是斷言不能直接用你的編程語言編寫,請爲它們編寫自動單元測試。將它們寫入符合項目開發過程風格的文檔或圖表中。
尋找具備相關概念集的模型,這些概念引導開發人員推斷預期的斷言,加速學習曲線並下降矛盾代碼的風險。
斷言定義了服務和實體修飾符的契約。
斷言在聚合上定義了不變性。
即便在同一個模塊中,隨着依賴性的增長,解釋設計的難度也會大幅增長。這增長了理解的負擔,限制了開發人員能夠處理的設計複雜性。隱式概念對此負擔的促進做用甚至超過了顯示的引用。
低耦合是面向對象設計的基礎。若是能夠,一直這樣作。消除圖中的全部其餘概念。而後類將徹底獨立,能夠單獨研究和理解。每一個這樣的自包含類都顯着減輕了理解一個模塊的負擔。
大多數有趣的對象最終都只能作一些沒法用基本元素來表示的東西。
所以:
在適當的狀況下,在定義操做時讓它返回類型與其參數的類型相同。若是實現者的狀態在計算中會被用到,那麼實現者實際上就是操做的一個參數,所以參數和返回值應該與實現者有相同的類型。這種操做就是在該類型的實例集合中的閉合操做。閉合操做提供了一個高層接口,而不會引入對其餘概念的依賴。
這種模式一般應用於值對象的操做。由於一個實體的生命週期在領域中具備重要意義,因此你不能創造一個新的實體來回答一個問題。也有一些操做在實體類型下閉合。能夠向其主題對象請求一個屬性對象並取回另外一個屬性。但總的來講,實體並非那種適合成爲計算結果的概念。因此,大多數狀況下,這是一個尋找值對象的機會。
你有時會陷入這種模式的一半。參數與實現者匹配,但返回類型不一樣,或者返回類型與接收者匹配,參數不一樣。這些操做並非閉合的,可是他們給與了思考閉合的一些優點的想象空間。
在程序軟件中不可能有真正的保證。僅以一種逃避斷言的方式命名,代碼可能會產生額外的反作用而這些反作用並無被排除在外。不管咱們的設計如何以模型爲導向,咱們仍然最終編寫程序來產生概念上的交互效果。而且咱們花費大部分時間在編寫樣板代碼上,而這些代碼並無實際增長任何意義或者行爲。本章中的釋意接口和其它模式有所幫助,可是它們不可能給傳統的面向對象提供形式上的嚴謹。
這些是聲明式設計背後的動機。這個術語對不少人來講意味着許多東西,但一般它指示一種編寫一個程序或者程序的某個部分的方式,做爲一種可執行的規範。對屬性的很是精確的描述實際控制着軟件。在它的各類形式中,能夠經過反射機制或編譯時經過代碼生成來完成(基於聲明自動生成傳統代碼)。這種方法容許其餘開發人員以表面價值接受聲明。這是一個絕對的保證。
若是開發人員有意或無心地繞過它們,不少聲明式方法可能會被破壞。當系統難以使用或限制過多時,這極可能發生。每一個人都必須遵照框架的規則才能得到聲明式編程的好處。
一旦你的設計有釋意接口,無反作用函數和斷言,你就會進入聲明式領域。聲明式設計的許多好處都是在您具備可交流其含義的可組合元素,而且具備特徵或明顯效果,或根本沒有可觀察效果時得到的。
柔性設計可使客戶端代碼使用聲明式的設計風格成爲可能。爲了說明這一點,下一節將介紹本章中的一些模式,以使規範更加靈活和聲明性。
從零開始建立一個嚴格的概念框架是你天天都不能作的事情。有時在項目的生命週期中,您會發現並改進其中的一個。可是你能夠常用和調整那些長期在你的領域或其餘領域創建起來的概念系統,其中一些已經通過了幾個世紀的精煉和提煉。例如,許多商業應用程序都涉及會計。會計定義了一套完善的實體和規則,能夠輕鬆適應深層模型和柔性設計。
有許多這樣的形式化的概念框架,但我我的最喜歡的是數學。讓人驚訝的是,在基本算法上作一些改變是多麼有用。不少領域包括數學。尋找它。挖出來。專業的數學是乾淨的,能夠經過清晰的規則組合起來,而且人們發現它很容易理解。
在本書的第8章討論一個真實世界的例子「Shares Math」,領域驅動設計。
有時人們會爲了靈活的組合而砍掉一些功能。有時候他們會把它封裝得很複雜。有時他們會尋求一致的粒度,使全部類別和操做達到類似的程度。這些都是過於簡單化的,不像通常規則那樣有效。可是他們經過基本問題來激發。
當模型或設計的元素被嵌入到一個總體結構中時,它們的功能會被複制。外部接口並不表示客戶端可能關心的全部內容。他們的意思很難理解,由於不一樣的概念是混合在一塊兒的。
相反,分解類和方法可能會使客戶端無心識去複雜化,迫使客戶端對象瞭解如何將小塊組合在一塊兒。更糟糕的是,一個概念可能徹底喪失。鈾原子的一半不是鈾。固然,重要的不是顆粒度的小大,但這只是顆粒度的來源。
所以:
將設計元素(操做、接口、類和聚合)分解爲內聚單元,同時考慮到您對領域重要分支的直覺。經過連續的重構觀察覈心的變化和穩定性,並尋找解釋這些切分方式的基本概念輪廓。對比模型與領域一致的方面,首先讓它成爲一個可行的知識領域。
基於深度模型的柔性設計產生了一組簡單的接口,這些接口邏輯上能夠在通用語言中做出合理的聲明,而且沒有無關選項的干擾和維護負擔。
做者:Zachary_Fan
出處:www.cnblogs.com/Zachary-Fan…
若是你想及時獲得我的自寫文章的消息推送,歡迎掃描下面的二維碼~。