學習DDD的意義
作為技術人,都有一個成為大牛的夢。
有些人可以通過自己掌握了比較底層、有深度、有難度的技術來證明自己的能力。
但對于絕大多數的應用研發工程師來說,其大部分的時間精力,會被消耗在讀不懂、講不清的屎山代碼中,以及復雜多變的業務迭代中。很少會有需要去接觸高深技術的機會,即便是接觸了,也很少有實踐應用的機會。
所以對于應用研發工程師來說,提高架構設計的能力,預防屎山代碼的產生,高效、高質的應對多變的業務需求,便是證明自己能力的關鍵。而DDD便是一個從業務層面指導架構設計的較為完備的理論體系。
DDD誕生的背景
這里我想從我個人的理解,分享下DDD產生的背景。(個人見解)
我們都了解,軟件誕生之初,就是幾個簡單的指令,那時候寫代碼,真的就是寫二進制,通過紙帶打孔的方式來交給機器運行。
隨著發展,軟件指令變得多樣,軟件也變得復雜,便又有了軟件研發上,從匯編語言到高級語言,再到面向對象編程的產生。
軟件本身功能的強大還不夠,為了應對社會的發展變化,就要求軟件自身有更好的擴展性,這便有了設計模式、設計原理等理念的產生。
在社會普遍信息化的今天,軟件更是被普及應用在了在各行各業、各種領域。軟件面臨的復雜度,不再僅僅是技術方案本身的復雜度,更多的是要面對軟件所屬行業、所屬領域的業務本身的復雜度。前者我們稱之為偶然復雜度,后者我們稱之為本質復雜度。DDD便由此產生。
DDD,中文名字叫領域驅動設計,"領域"一詞,表示的是一個業務范圍。它強調從業務角度去設計軟件。
經典DDD書籍《領域驅動設計:軟件核心復雜度應對之道》,這里所說的軟件核心復雜度,應該指的就是上文說的本質復雜度吧。
DDD為什么難學
DDD誕生之初,是一個純粹的理論體系,它包含了各種復雜且難以理解的概念。
在接下來的發展中,又有追捧者根據自己對DDD的理解,發展出不同的落地方案,比如:六邊形架構、洋蔥架構、CQRS、ES、整潔架構等。這就使得DDD的知識體系更加復雜。
再加上DDD理論本身并不是一個放之四海皆準的方案,需要具體場景具體判斷,這就大大提高了DDD的學習應用門檻。所以我經常開玩笑說:DDD最大的價值就是用來吹牛逼。
DDD的核心目的
與設計模式在實際研發中的應用一樣,DDD的應用也需要我們在合適的場景選擇合適的設計。那么如何判斷場景合適與否呢?
要回答這個問題,需先搞清楚,DDD的設計理念的核心目的是什么。
DDD標榜自己是治理核心復雜度,但我想問,復雜度為什么需要被治理?復雜度可以通過治理被降低嗎?
首先,復雜度為什么需要被治理。這是因為人的認知能力是有限的,當事物的復雜度超出一定范圍,就會給人帶來認知負荷,阻礙人們對事物的理解。
其次,復雜度能否被降低。個人更傾向于Linus Torvalds所認為的:復雜度并不會因為被治理而降低。比如操作系統,雖有各種設計,但依舊復雜。畢竟要實現的功能擺在那。
復雜度雖然不能被降低,但我們可以通過一些手段,比如分離關注點、封裝屏蔽細節等,來降低復雜度給人們帶來的理解上的難度。
所以,我更相信,與其說DDD是治理核心復雜度,不如說DDD的核心目的是提高系統的可理解性。
了解了DDD的核心目后,我們就可以通過這樣的方式來判斷,在某個場景下是否適合引入DDD的某個理念:引入DDD的設計理念后,系統(代碼)是否更清晰、更易理解。
這里還需要強調的是:DDD是提高可理解性的手段,可理解性才是核心目的。當在某個場景下,該手段不能幫我們提高可理解性時,那就果斷放棄。千萬不要為了用DDD而用DDD。
關于可理解性
可理解性,也就是我們搞清楚一個事物的難易程度。
其重要性不言而喻:一個難以理解、難以搞清楚的系統,一定是一個難以維護的系統,其迭代效率一定是較低的,Bug率一定是較高的,質量絕對是堪憂的。
根據熵增理論,一個系統如果沒有外力的干預,一定會變得越來越雜亂。伴隨著系統的雜亂,人們對系統的理解也會變得越來越困難。
所以,個人覺著系統的可理解性的重要性絕不亞于可擴展性,甚至優先級高于可擴展性。
那么DDD有哪些比較關鍵的手段來提高系統的可理解性呢?我認為有這么幾個比較關鍵的點:統一語言、領域分解、領域建模。
統一語言,它通過邊界清晰的、完整一致的抽象命名,來降低人們的認知負荷。猶如人類將所依賴的食物一致的劃分為蔬菜、水果、糧食等。
領域分解,它通過分治的手段,實現關注點的分離,從而降低認知負荷。比如,計算機包括了CPU和內存等模塊,當你想要搞清楚計算機是如何實現計算的。你只需要把注意力聚焦在CPU上,而幾乎不需要被其他模塊的實現細節所干擾。
領域建模,它利用面向對象的設計,較為直觀的映射業務現實,從而提高可理解性。比如,地球儀就是對地球的建模,如果想清楚的了解地球,地球儀一定比地圖更直觀。
總結
個人認為,學習一門技術,首先要搞清楚這門技術能幫我們實現什么目標,解決什么問題。接下來才是學習這門技術的具體手法和技巧。只有這樣,我們才能在一個清晰的目標下,有目的、有選擇的甚至是優化改進的,應用這些手法和技巧。
所以本文主要是認知篇,介紹了DDD的背景和難點,以及重要的DDD能夠幫我們實現的核心目標:提高系統的可理解性。
有了本文章的鋪墊,下篇文章,我將重點介紹DDD中,那些比較重要、比較有價值的手法和技巧。