DDD最近幾年比較熱,由於它在某種程度上確實解決了一些設計問題,它強調在軟件設計的初期就引入領域專家,始終圍繞着軟件要解決的 核心領域問題 來展開,很好的避免了一些架構過分設計,過早的引入非領域問題設計,好比事務,併發。它圍繞着幾個核心概念——Entity, Value Object, Aggregate, Repository, Domain Service, Domain Event——來設計並實現功能,整個團隊用一致的工程語言來描述和組織相關的代碼,比較有效率,代碼質量也有必定的保證。可是它也有其侷限性,我用《面向對象分析與設計》的解密文本的應用來舉例子,題目描述很簡單,給定一個密文,設計一個解密程序。若是生硬地沿着DDD的思路,咱們發現很難去識別相關的Entity, Value Object, Service並展開相應的設計。對於這樣的問題,面向對象設計給了一個很是漂亮的解答,它模擬了一個寫了密文的黑板,有衆多擁有某些知識的觀察者在觀察並根據本身的知識——好比單字母在英語中,通常是I或者A;好比三個字母最後一個是E的極可能是THE;好比結尾連續兩個字母同樣極可能是EE …… ——嘗試着解密部分密文,而後通知其餘的觀察者,從中咱們能夠學習到面向對象設計如何針對一個很難入手的問題,經過分解一個一個細粒度的對象,每一個對象只解決一部分小的問題,最終各個對象經過交互,來獲得最終的答案,所使用的 Blackboard模型 不在這裏展開講了,有興趣的讀者能夠自行深刻了解,很是推薦你們認真學習這個問題解決過程,可以很深切的體會到面向對象設計的思惟。從中咱們能夠看出面向對象設計通常不關心數據,它更關心的是行爲。一個問題在現實中如何被解決,並經過模擬這個解決過程,定義其中所牽涉到的對象,行爲,以及交互,從這方面說,它與DDD是不太相同的。不管DDD如何強調要設計充血的Entity模型,在落地過程當中,識別Entity和Aggregate的階段很是容易陷入設計出大量貧血Entity的狀況,經過setter/getter,而不是清晰的包含領域意義的行爲來操做數據;陷入過早的考慮數據之間的關聯而不是對象彼此之間的交互的陷阱。程序員
DDD自己並非傳統數據驅動設計的變形,儘管數據驅動過去是,如今仍然是一種很是有效的設計方法。數據庫
Get the data structures correct, and the code will write itself.數據結構
早期的C程序員解決問題,都是定義好相關的struct,詳細到xxx字段是用int仍是char,而後圍繞struct來開發相關的方法並組織這些方法的調用過程。傳統的企業級應用開發也是先作好數據庫的設計,整個應用層是圍繞着數據庫來開發的。說到這裏,想扯一點Go語言的語法設計,只是我的感受,由於Go語言的設計者們都是資深的unix c程序員出身,Go語言的面向對象的語法設計是有點彆扭的,struct embedding,帶接收者的方法定義,帶來了繼承,多態,覆寫概念上的一些理解障礙。架構
既然談到了數據驅動設計,就再多說幾句Kubernetes和Spring Cloud,如今這兩種是常見的微服務架構落地方案了,他們就有很大的不一樣,Kubernetes經過定義精妙的Pod,Deployment,Service,DaemonSet,Ingress, CustomResourceDefinition等數據結構,全部的核心組件經過監控etcd的數據變化來調整自身的狀態,在不增長複雜性的基礎上提供了很好的擴展性。反觀Spring Cloud,基於面向對象的設計,提供了一個又一個的抽象,架構的複雜性和擴展性造成了正相關的關係,致使Spring Cloud總體的複雜度愈來愈高。很是佩服Google的Kubernetes的總體架構設計理念以及定義核心數據結構的功力。併發
DDD是一種自底向上的設計,很是適合企業級產品的團隊開發,由於企業級產品絕大多數都是圍繞着明確的領域數據來實現功能,並且DDD有不少好的實踐與模式幫助解決不少開發過程當中常見的問題。微服務
面向對象設計是一種自頂向下的設計,更普適一點,更難掌握一點,很難概括出有明確的步驟指導解決某一類問題,正如《面向對象分析與設計》中說的同樣,在不少狀況下,完成詳細設計後,識別Entity也是其中的一步,不過是在至關靠後的設計階段了。學習
DDD和麪向對象設計都是核心領域建模的方法,要完成真正的產品,還有不少方面要考慮。在軟件開發領域,還跟多年前的論斷同樣,沒有銀彈!架構設計
最後,安利兩本書,《面向對象分析與設計》和《實現領域驅動設計》設計