本書是Eric Evans對他自己寫的《領域驅動設計-軟件核心復雜性應對之道》的一本字典式的參考書,可用於快速查找《領域驅動設計》中的諸多概念及其簡明解釋。
其它本系列其它文章地址:
[譯文]Domain Driven Design Reference(一)—— 前言
[譯文]Domain Driven Design Reference(二)—— 讓模型起作用
[譯文]Domain Driven Design Reference(三)—— 模型驅動設計的構建模塊
Ⅰ.讓模型起作用
領域驅動設計是一種開發復雜軟件的方法:
1.專注核心領域。
2.探索領域從業者和軟件從業者的創造性協作模式。
3.在一個明確的限界上下文內講通用語言。
DDD的三點總結依賴於本手冊定義的術語來定義。
很多項目做建模工作最終沒有獲得太多的實際好處。DDD模式從項目中提煉成功的實踐使得建模帶來了巨大的好處。總的來說,他們提出了一個與先從細節再到高層次的視角【1,在DDD之前我們大部分都習慣於先進行數據表的設計】完全不同的建模和軟件開發的方式。嚴格的建模慣例必須平衡好與非技術人員【2,一般這里指領域專家】合作進行的模型探索。戰術和戰略必須結合才能成功,DDD同時涉及戰術和戰略的設計。
限界上下文
任何大型項目都有多個模型。它們出現的原因很多。兩個子系統通常服務於非常不同的用戶群體,具有不同的工作,其中建立不同的模型可能是有作用的。團隊獨立工作由於缺乏溝通可能以不同的方式解決了同樣的問題。工具集也可能不同,這意味着程序代碼不能共享。
多個模型是不可避免的,而當基於不同模型的代碼被合並時,軟件變得充滿BUG,不可靠,而且難以理解。團隊成員之間的交流變得困惑。在什么情況下不應該使用模型通常是不清楚的。
模型表達式與其他任何短語一樣,僅在上下文中具有含義。
因此:
明確定義模型適用的上下文。根據團隊組織,應用程序特定部分的使用情況以及例如代碼庫和數據庫模式等物理表現明確設置邊界。應用“持續集成”可使模型概念和術語在這些范圍內保持嚴格一致,但不要被外部問題分散或混淆。在上下文中標准化一個單獨的開發過程,這個開發過程不需要在其他地方使用。
通用語言
首先寫下一個句子,
然后將它分成小段,
再將它們打亂並重新排序。
仿佛是巧合一樣,
短語的順序對意思完全沒有影響。
--Lewis Carroll, "Poeta Fit, Non Nascitur"
要想創建一種靈活的、蘊含豐富知識的設計,需要一種通用的、共享的團隊語言,這種語言應該是時刻進行檢驗的,遺憾的是,在軟件項目上很少出現這樣的檢驗。
在一個單一的限界上下文內,語言可能會以某種方式被破壞,削弱了在應用復雜建模上的努力。如果該模型僅用於為團隊的技術人員繪制UML圖,那么這對DDD核心的創造性合作沒有任何貢獻。
領域專家使用他們的術語,而技術團隊成員有自己的語言來從設計的角度討論這個領域。日常討論的術語與代碼中嵌入的術語(最終是軟件項目最重要的產品)。甚至同一個人在說和寫中都會使用不同的語言,使得這個領域中最尖銳的表達常常以暫時的形式出現,而這種形式永遠不會在代碼中甚至在書面中被捕捉到。
翻譯會導致溝通不暢,使得知識匱乏。
然而,這些語言都不能成為一種共同的語言,因為沒有一種服務於所有需求。
領域專家應該反對別扭或不足以傳達領域理解的術語或結構;開發人員應該注意有無歧義或不一致將妨礙設計。
在談論這個系統的時候,帶上模型。使用模型的元素和交互來大聲描述場景,以模型允許的方式結合概念。找到更簡單的方法來說出你需要說的話,然后把這些新的想法帶回圖表和代碼中。隨着語言的普及,模型不僅僅是一個設計品。它成了開發人員和領域專家一起要完成的不可或缺的事情。
因此:
使用模型作為語言的支柱。保證團隊在團隊和代碼中的所有交流中不懈地運用這種語言。在一個限界上下文中,在圖表,寫作,尤其是交流中使用相同的語言。
意識到言語的改變就是對模型的改變。
通過實驗替代表達式來體現替代模型來解決困難。然后重構代碼,重命名類,方法和模塊以符合新模型。解決對話中的術語混淆,就像我們對普通單詞的意義認知是一致的一樣。
持續集成
一旦定義了限界上下文,我們就必須保持它的健康。
當許多人在一個相同的限界上下文里工作時,模型碎片化會是一個強烈的趨勢。團隊越大,問題就越大,但只有三四個人就會遇到嚴重的問題。然而,將系統分解成更小的上下文最終會失去一個整合和內聚的價值。
因此:
經常研究一個合並所有代碼和其它實現工件的過程,通過自動化測試來快速標記碎片。不懈的運用通用語言,隨着概念在不同人的頭腦中的演變,逐漸形成對模型的共同觀點。
模型驅動設計
將代碼與底層模型緊密聯系在一起給出了代碼的含義,並使模型具有相關性。
如果設計或其中心部分沒有映射到領域模型,那么該模型沒有什么價值,並且軟件的正確性是可疑的。同時,模型和設計功能之間的復雜映射是難以理解的,並且實際上不可能保持的像設計的改變一樣。在分析和設計之間設立一道紅線,使得在每一個這樣的活動中獲得的洞察力都不會影響到另一個。
從模型中提取在設計中使用的術語和職責的基本分配。代碼成為模型的表達式,所以對代碼的改變就是對模型的改變。從而它的影響必然涉及到該項目的其余活動。
因此:
設計軟件系統的一部分,以非常直觀的方式反映領域模型,以便映射是顯而易見的。重新審視模型並修改它,以便在軟件中更自然地實現,即使您試圖使其更深入地反映領域。需要一個單一的模型,來除了支持一個順暢的通用語言之外,同時滿足目的正確。
動手建模者
如果編寫代碼的人不對模型負責,或者不知道如何使模型適用於應用程序,那么模型與軟件無關。如果開發人員沒有意識到改變代碼會改變模型,那么他們的重構就會削弱模型而不是加強模型。與此同時,當建模者與實現過程分離時,從未獲得或很快失去對實現約束的感覺。模型驅動設計的基本約束是模型支持有效的實現並且抽象出對領域的關鍵洞察,已經過去了一半,所產生的模型將是不切實際的。最后,如果分工阻止了這種協作,經驗豐富的設計師的知識和技能不會轉移到其他開發人員,這是傳達了模型驅動設計編碼的微妙之處。
因此:
任何對模型有貢獻的技術人員都必須花費一些時間來接觸代碼,無論他在項目中扮演什么主要角色。任何負責更改代碼的人都必須學會通過代碼來表達模型。每個開發者都必須參與一些關於模型的討論,並與領域專家聯系。那些以不同方式作出貢獻的人,必須有意的聘請那些在一個通過通用語言動態交換模型想法中接觸代碼的人。
重構深入的洞察力
使用一套經過驗證的基本構建模塊以及一致的語言為開發工作帶來了一些清晰的思路。這避免了真正找到一個尖銳模型的挑戰,一個捕獲領域專家的微妙擔憂和可以推動一個切實的設計。一個在膚淺的表面下的模型抓住的本質是一個深層的模型。這應該使軟件更符合領域專家的思維方式,並且更加符合用戶的需求。
傳統意義上,重構是被用於描述由技術動機進行代碼轉換的詞。重構也可以通過對領域的洞察以及對代碼中模型或其表達的相應改進來激發。
復雜的領域模型很少發揮作用,除非通過重構的迭代過程來開發,包括領域專家與有興趣了解該領域的開發者的密切參與。
作者:Zachary
出處:https://zacharyfan.com/archives/287.html
▶關於作者:張帆(Zachary,個人微信號:Zachary-ZF)。堅持用心打磨每一篇高質量原創。歡迎掃描右側的二維碼~。
定期發表原創內容:架構設計丨分布式系統丨產品丨運營丨一些思考。
如果你是初級程序員,想提升但不知道如何下手。又或者做程序員多年,陷入了一些瓶頸想拓寬一下視野。歡迎關注我的公眾號「跨界架構師」,回復「技術」,送你一份我長期收集和整理的思維導圖。
如果你是運營,面對不斷變化的市場束手無策。又或者想了解主流的運營策略,以豐富自己的“倉庫”。歡迎關注我的公眾號「跨界架構師」,回復「運營」,送你一份我長期收集和整理的思維導圖。