領域驅動設計,讓程序員心中有碼(八)

 回顧

  領域驅動是十五年前,由Eric Evans提出的解決軟件工程復雜性問題的方法,作者從自己多年軟件開發的角度出發,通過引入領域驅動設計的概念以及一系列戰略設計模式和戰術方法,為混沌的軟件開發領域帶來了一縷陽光。

  在過去的許多年,我經歷了從技術崗位到管理崗位的變化,也深深的意識到,每一個軟件的設計與實施過程之艱辛,缺乏一些科學的管理方法,只會讓人疲于奔命,毫無積累,尤其是對于開發過程而言,看似枯燥乏味的編碼過程,卻充滿了更大的變數。

  例如,在以前傳統企業開發中設計系統架構時,往往會使用三層架構,用戶界面層,業務層,數據訪問層上手就來,但是卻看似三層分立,但是由于開發者開發過程中出現的一些不規范問題,容易在用戶界面層和數據層中堆積大量的冗余代碼,而中間的業務層反而非常單薄,代碼行很少,僅僅只是實現對象的輸出而已。用戶界面層和數據訪問層就很容易成為腐化代碼,隨著需求的變更,容易變成大泥球系統。

  尤其是那些核心模塊的用戶界面層代碼,輕易就突破了上千行,甚至上萬行,這些代碼并非完全都是由于不規范的操作造成的,一定程度上也是由于個別開發者的代碼不規范,形成的破窗效應。不管發生了什么,這些代碼最終成為一座屎山。如果再加上古人寫的存儲過程,對不起,我選擇自閉。

  屎山的命運往往都是一樣的,要么重構成功,得以逆天改命,要么被公司拋棄,成為企業發展過程中的一座重要里程碑,要么跟著公司一起,成為創業者的黃粱美夢。 是什么造成了屎山?是需求嗎?

需求控制或不控制?

  用戶需求就像一個關在籠子里的獅子,控制或不控制,這是個問題。

  對于互聯網公司而言,一定程度上來說,需求來源于產品經理的靈感乍現,或來源于對競品(被抄襲品)功能的把握,不同產品經理對于產品的規劃總是不盡相同,以及老板和用戶的反饋也是產品需求變化的原因,需求的累積也會讓開發者為了修改而疲于奔命,而且面向互聯網的產品往往比項目型軟件成品面向更大的群體,擁有更長的生存周期,開發者為了應對需求而不節制的更改,容易成為試錯,甚至會影響企業的生存。

  所以使用領域驅動設計方法對后端的結構進行改造甚至中臺化改造成為一種非常有效的解決方案,而對于面向用戶的前臺,以及為前臺而生的BFF則由于更側重于用戶數據交互,而被排除于領域控制之外,(即 Backend For Frontend)(當然,過度的依賴前端表現層,也容易造成前端代碼的冗余,事實上前端和客戶端代碼也最容易成為屎山,這是后話,就不贅述了。)

  除互聯網公司需要領域驅動的方法外,傳統軟件企業也同樣需要,在企業發展過程中,積累的無數項目,大部分項目都存在一些普遍性的共性,那就是為了盲目追求實現,而忽略了軟件代碼的健壯性和可維護性,能否把功能強推下去,取決于項目經理對于甲方的控制力,一旦掌握優秀溝通技巧的關鍵崗位離職,這些項目都將成為一個個不知何時會爆發的地雷。軟件企業項目的復雜性,有別于互聯網企業的面對業務快速裂變帶來的變化,往往更側重于業務層面的規模復雜,一個系統的大幾百個功能點,如何保證質量,時間,成本三者的平衡,這是個恒古不變的問題。

  需求讓軟件充滿變數、而規模、質量屬性也同樣會影響到軟件的變化,要打破僵局,或許,領域驅動看似是一種不錯的選擇。

看似破解之道

  然而,領域驅動的實踐過程卻充滿坎坷,主要在于 Evans的原書,知識密度之稠,遠甚于開發者熱衷的技術話題。要解決某些技術問題,依托互聯網的資源,或許能很快找到解決問題的方法,但是面對領域驅動設計,卻讓人望而生畏,許多人都說雖然聽說這個概念的時間不在短暫,但是卻總覺得沒有入門。

  單純的從概念上看,引入的統一語言,領域存儲庫,實體,值對象,聚合根,限界上下文,上下文映射等名詞,理解上似乎很容易,但是要付諸實踐卻并非易事。尤其還需要把這些東西引入到企業實戰過程,更是難上加難。領域驅動設計方法,并不像那些技術書籍一般,拿著書上的方法,總能在自己公司找到可以實踐的點。 Evans的書也好,其他書也好,都只是方法,而不是一套行之有效,馬上就能使用的方案,需要團隊花費大量時間去應用實踐。

  例如,一種最常見的領域驅動架構的實踐是簡單四層的領域驅動分層結構,在不能有效理解關注度分離的前提下,架構代碼同樣能成為屎山,而且似乎由于開發者知識傳承的缺失,極其容易讓人難以理解和更不用說代碼質量的提升,只能成為倡導者實現個人價值提升的練兵場。

個人想法

  我個人認為,領域驅動設計方法,作為一種解決復雜問題的應對之道,確實值得企業對其持續關注,但是否有一種能夠便捷的方法,讓參與者能夠更快的將這么好的方法論在產品研發過程中融匯貫通,形成更高效的應用過程呢,下面是我根據一些討論和學習過程,形成的一點思考,希望能給大家帶來一絲啟發。

  1,如何開始改變企業文化?這是來自于《實例化需求》中提出的一個問題,作者的原意是認為要實踐TDD,需要進行文化變革,事實上實踐DDD或許同樣如此。康威定律指出:一個組織拿出的技術方案設計,實際上是一個組織溝通方式的體現。你的組織真的準備好開始接受這種思想的考驗了嗎?這是個問題。

  2、確保你得到管理層的支持。這也是來自于《實例化需求》中的原話,毫無疑問,如果缺乏管理層的認可和支持,過程變更成功的幾率幾乎為零。

  3、忘掉敏捷、忘掉領域驅動、忘掉概念。由于領域驅動設計方法的看似晦澀難懂,容易讓組織實踐領域驅動的人陷入學院派或教條主義的誤區,這表現在:組織者更傾向于使用專家給出的標準術語對領域驅動設計的方法進行解讀而缺乏與企業實際相結合的形式。我個人認為,為了更好的推廣領域驅動設計的應用過程,不應該局限于教條主義,不要過分關注于概念、框架或自動化的工具,而是把領域驅動設計過程,解釋成一種發現需求、解釋需求之間的相關性、收集實例、設計測試、以及形成可自解釋的開發代碼的過程。

  4、從一個小項目和簡單項目開始,探索建立一套行之有效的方法。從一個業務結構清晰、容易細分出應用場景和業務活動的項目出發,避免陷入大項目難以控制邊界的過程,而且大項目如果沒能更好的實施,只會一發不可收拾。有網友說,由于項目需求的極度不確定性,所以他覺得有必要引入領域驅動設計的方法來解決這個問題,我個人認為,這樣的做法只會導致項目更加一發不可收拾,尤其是在一個學習能力并不好的組織中開展領域驅動設計實踐、且大家都對這套理論一知半解的前提下。

  5,從產品語言中提煉統一語言。axure軟件的流行,讓通過原型文檔這種可視化需求表達成為主流。原型語言與需求的高度貼近,也便于產品研發團隊從中形成統一語言。

  6,形成可用的產品術語表。從統一語言出發,形成可以指導編程的術語表,并形成對應的中英文對照表,可以便捷的為開發過程提供變量命名的規則,尤其是許多開發者本身的英語水平就不是特別好,如果形成這樣的規則,或許能為代碼的開發過程帶來許多便利。

  7,從統一語言和需求中提煉用例圖。按照張逸老師的說法,用例或用戶故事應該滿足6w特性,可以嘗試站在用例的角度思考這樣的問題:

  • 到底誰是用戶?需要執行這一活動的角色到底是誰?
  • 為什么需要查詢功能?
  • 究竟要查詢什么樣的內容?
  • 為什么需要了解分配給我的任務情況?

  8,從用例圖和業務流程中識別限界上下文。沒必要一開始就采用四色建模法,采用比較簡單的領域場景分析的用例分析方法進行分析,同樣是不錯的選擇,例如從分析業務活動間的語義相關性,也是一種值得嘗試的方法。

總結

  人生三境界:看山是山,看水是水;看山不是山,看水不是水;看山還是山,看水還是水。大概技術領域也同樣如此。

  回到一個古老的問題,有人問:如何給一個變量命名,詞窮了怎么辦?專家的回答是,按領域驅動設計的方法對變量進行命名。這就是實踐領域驅動設計的大師高論,已經到了看山還是山的地步。而普通開發者們,總是看了幾篇領域驅動設計的文章,就會以為嗯,我遇到的這些問題,用領域驅動能解決,然后,就陷入一堆概念之中不可自拔。

  實踐是檢驗真理的唯一標準,唯有真的使用一個項目開始實踐,才能真正體會領域驅動設計的精髓。領域驅動設計思想,是一種充滿魅力的軟件理論方法,然而要把這套理論真的用起來,依然需要經歷一個從新手到高級新手,再到勝任者、精通者和專家的學習過程。本文也同樣屬于一位處于新手村學習者的個人見解,班門弄斧,期待能拋磚引玉,措辭多有不當,還望海涵。

  參考資料:1、Eric Evans《領域驅動設計·軟件核心復雜性應對之道》

          2、張逸 《GitChat講座:領域驅動設計實戰》

         3、Gojko Adzic《實例化需求》

  ps:我本不想打廣告,不過我覺得張逸老師的課程確實講得挺不錯的,有興趣可以關注一下。

 

posted @ 2019-06-19 09:16 溪源More 閱讀(...) 評論(...) 編輯 收藏
内部期期公开一波中特