领域驱动设计,让程序员心中有码(八)
領(lǐng)域驅(qū)動是十五年前,由Eric Evans提出的解決軟件工程復(fù)雜性問題的方法,作者從自己多年軟件開發(fā)的角度出發(fā),通過引入領(lǐng)域驅(qū)動設(shè)計的概念以及一系列戰(zhàn)略設(shè)計模式和戰(zhàn)術(shù)方法,為混沌的軟件開發(fā)領(lǐng)域帶來了一縷陽光。
在過去的許多年,我經(jīng)歷了從技術(shù)崗位到管理崗位的變化,也深深的意識到,每一個軟件的設(shè)計與實施過程之艱辛,缺乏一些科學(xué)的管理方法,只會讓人疲于奔命,毫無積累,尤其是對于開發(fā)過程而言,看似枯燥乏味的編碼過程,卻充滿了更大的變數(shù)。
例如,在以前傳統(tǒng)企業(yè)開發(fā)中設(shè)計系統(tǒng)架構(gòu)時,往往會使用三層架構(gòu),用戶界面層,業(yè)務(wù)層,數(shù)據(jù)訪問層上手就來,但是卻看似三層分立,但是由于開發(fā)者開發(fā)過程中出現(xiàn)的一些不規(guī)范問題,容易在用戶界面層和數(shù)據(jù)層中堆積大量的冗余代碼,而中間的業(yè)務(wù)層反而非常單薄,代碼行很少,僅僅只是實現(xiàn)對象的輸出而已。用戶界面層和數(shù)據(jù)訪問層就很容易成為腐化代碼,隨著需求的變更,容易變成大泥球系統(tǒng)。
尤其是那些核心模塊的用戶界面層代碼,輕易就突破了上千行,甚至上萬行,這些代碼并非完全都是由于不規(guī)范的操作造成的,一定程度上也是由于個別開發(fā)者的代碼不規(guī)范,形成的破窗效應(yīng)。不管發(fā)生了什么,這些代碼最終成為一座屎山。如果再加上古人寫的存儲過程,對不起,我選擇自閉。
屎山的命運往往都是一樣的,要么重構(gòu)成功,得以逆天改命,要么被公司拋棄,成為企業(yè)發(fā)展過程中的一座重要里程碑,要么跟著公司一起,成為創(chuàng)業(yè)者的黃粱美夢。 是什么造成了屎山?是需求嗎?
需求控制或不控制?
用戶需求就像一個關(guān)在籠子里的獅子,控制或不控制,這是個問題。
對于互聯(lián)網(wǎng)公司而言,一定程度上來說,需求來源于產(chǎn)品經(jīng)理的靈感乍現(xiàn),或來源于對競品(被抄襲品)功能的把握,不同產(chǎn)品經(jīng)理對于產(chǎn)品的規(guī)劃總是不盡相同,以及老板和用戶的反饋也是產(chǎn)品需求變化的原因,需求的累積也會讓開發(fā)者為了修改而疲于奔命,而且面向互聯(lián)網(wǎng)的產(chǎn)品往往比項目型軟件成品面向更大的群體,擁有更長的生存周期,開發(fā)者為了應(yīng)對需求而不節(jié)制的更改,容易成為試錯,甚至?xí)绊懫髽I(yè)的生存。
所以使用領(lǐng)域驅(qū)動設(shè)計方法對后端的結(jié)構(gòu)進(jìn)行改造甚至中臺化改造成為一種非常有效的解決方案,而對于面向用戶的前臺,以及為前臺而生的BFF則由于更側(cè)重于用戶數(shù)據(jù)交互,而被排除于領(lǐng)域控制之外,(即 Backend For Frontend)(當(dāng)然,過度的依賴前端表現(xiàn)層,也容易造成前端代碼的冗余,事實上前端和客戶端代碼也最容易成為屎山,這是后話,就不贅述了。)
除互聯(lián)網(wǎng)公司需要領(lǐng)域驅(qū)動的方法外,傳統(tǒng)軟件企業(yè)也同樣需要,在企業(yè)發(fā)展過程中,積累的無數(shù)項目,大部分項目都存在一些普遍性的共性,那就是為了盲目追求實現(xiàn),而忽略了軟件代碼的健壯性和可維護性,能否把功能強推下去,取決于項目經(jīng)理對于甲方的控制力,一旦掌握優(yōu)秀溝通技巧的關(guān)鍵崗位離職,這些項目都將成為一個個不知何時會爆發(fā)的地雷。軟件企業(yè)項目的復(fù)雜性,有別于互聯(lián)網(wǎng)企業(yè)的面對業(yè)務(wù)快速裂變帶來的變化,往往更側(cè)重于業(yè)務(wù)層面的規(guī)模復(fù)雜,一個系統(tǒng)的大幾百個功能點,如何保證質(zhì)量,時間,成本三者的平衡,這是個恒古不變的問題。
需求讓軟件充滿變數(shù)、而規(guī)模、質(zhì)量屬性也同樣會影響到軟件的變化,要打破僵局,或許,領(lǐng)域驅(qū)動看似是一種不錯的選擇。
看似破解之道
然而,領(lǐng)域驅(qū)動的實踐過程卻充滿坎坷,主要在于?Evans的原書,知識密度之稠,遠(yuǎn)甚于開發(fā)者熱衷的技術(shù)話題。要解決某些技術(shù)問題,依托互聯(lián)網(wǎng)的資源,或許能很快找到解決問題的方法,但是面對領(lǐng)域驅(qū)動設(shè)計,卻讓人望而生畏,許多人都說雖然聽說這個概念的時間不在短暫,但是卻總覺得沒有入門。
單純的從概念上看,引入的統(tǒng)一語言,領(lǐng)域存儲庫,實體,值對象,聚合根,限界上下文,上下文映射等名詞,理解上似乎很容易,但是要付諸實踐卻并非易事。尤其還需要把這些東西引入到企業(yè)實戰(zhàn)過程,更是難上加難。領(lǐng)域驅(qū)動設(shè)計方法,并不像那些技術(shù)書籍一般,拿著書上的方法,總能在自己公司找到可以實踐的點。?Evans的書也好,其他書也好,都只是方法,而不是一套行之有效,馬上就能使用的方案,需要團隊花費大量時間去應(yīng)用實踐。
例如,一種最常見的領(lǐng)域驅(qū)動架構(gòu)的實踐是簡單四層的領(lǐng)域驅(qū)動分層結(jié)構(gòu),在不能有效理解關(guān)注度分離的前提下,架構(gòu)代碼同樣能成為屎山,而且似乎由于開發(fā)者知識傳承的缺失,極其容易讓人難以理解和更不用說代碼質(zhì)量的提升,只能成為倡導(dǎo)者實現(xiàn)個人價值提升的練兵場。
個人想法
我個人認(rèn)為,領(lǐng)域驅(qū)動設(shè)計方法,作為一種解決復(fù)雜問題的應(yīng)對之道,確實值得企業(yè)對其持續(xù)關(guān)注,但是否有一種能夠便捷的方法,讓參與者能夠更快的將這么好的方法論在產(chǎn)品研發(fā)過程中融匯貫通,形成更高效的應(yīng)用過程呢,下面是我根據(jù)一些討論和學(xué)習(xí)過程,形成的一點思考,希望能給大家?guī)硪唤z啟發(fā)。
1,如何開始改變企業(yè)文化?這是來自于《實例化需求》中提出的一個問題,作者的原意是認(rèn)為要實踐TDD,需要進(jìn)行文化變革,事實上實踐DDD或許同樣如此??低芍赋?#xff1a;一個組織拿出的技術(shù)方案設(shè)計,實際上是一個組織溝通方式的體現(xiàn)。你的組織真的準(zhǔn)備好開始接受這種思想的考驗了嗎?這是個問題。
2、確保你得到管理層的支持。這也是來自于《實例化需求》中的原話,毫無疑問,如果缺乏管理層的認(rèn)可和支持,過程變更成功的幾率幾乎為零。
3、忘掉敏捷、忘掉領(lǐng)域驅(qū)動、忘掉概念。由于領(lǐng)域驅(qū)動設(shè)計方法的看似晦澀難懂,容易讓組織實踐領(lǐng)域驅(qū)動的人陷入學(xué)院派或教條主義的誤區(qū),這表現(xiàn)在:組織者更傾向于使用專家給出的標(biāo)準(zhǔn)術(shù)語對領(lǐng)域驅(qū)動設(shè)計的方法進(jìn)行解讀而缺乏與企業(yè)實際相結(jié)合的形式。我個人認(rèn)為,為了更好的推廣領(lǐng)域驅(qū)動設(shè)計的應(yīng)用過程,不應(yīng)該局限于教條主義,不要過分關(guān)注于概念、框架或自動化的工具,而是把領(lǐng)域驅(qū)動設(shè)計過程,解釋成一種發(fā)現(xiàn)需求、解釋需求之間的相關(guān)性、收集實例、設(shè)計測試、以及形成可自解釋的開發(fā)代碼的過程。
4、從一個小項目和簡單項目開始,探索建立一套行之有效的方法。從一個業(yè)務(wù)結(jié)構(gòu)清晰、容易細(xì)分出應(yīng)用場景和業(yè)務(wù)活動的項目出發(fā),避免陷入大項目難以控制邊界的過程,而且大項目如果沒能更好的實施,只會一發(fā)不可收拾。有網(wǎng)友說,由于項目需求的極度不確定性,所以他覺得有必要引入領(lǐng)域驅(qū)動設(shè)計的方法來解決這個問題,我個人認(rèn)為,這樣的做法只會導(dǎo)致項目更加一發(fā)不可收拾,尤其是在一個學(xué)習(xí)能力并不好的組織中開展領(lǐng)域驅(qū)動設(shè)計實踐、且大家都對這套理論一知半解的前提下。
5,從產(chǎn)品語言中提煉統(tǒng)一語言。axure軟件的流行,讓通過原型文檔這種可視化需求表達(dá)成為主流。原型語言與需求的高度貼近,也便于產(chǎn)品研發(fā)團隊從中形成統(tǒng)一語言。
6,形成可用的產(chǎn)品術(shù)語表。從統(tǒng)一語言出發(fā),形成可以指導(dǎo)編程的術(shù)語表,并形成對應(yīng)的中英文對照表,可以便捷的為開發(fā)過程提供變量命名的規(guī)則,尤其是許多開發(fā)者本身的英語水平就不是特別好,如果形成這樣的規(guī)則,或許能為代碼的開發(fā)過程帶來許多便利。
7,從統(tǒng)一語言和需求中提煉用例圖。按照張逸老師的說法,用例或用戶故事應(yīng)該滿足6w特性,可以嘗試站在用例的角度思考這樣的問題:
到底誰是用戶?需要執(zhí)行這一活動的角色到底是誰?
為什么需要查詢功能?
究竟要查詢什么樣的內(nèi)容?
為什么需要了解分配給我的任務(wù)情況?
8,從用例圖和業(yè)務(wù)流程中識別限界上下文。沒必要一開始就采用四色建模法,采用比較簡單的領(lǐng)域場景分析的用例分析方法進(jìn)行分析,同樣是不錯的選擇,例如從分析業(yè)務(wù)活動間的語義相關(guān)性,也是一種值得嘗試的方法。
總結(jié)
人生三境界:看山是山,看水是水;看山不是山,看水不是水;看山還是山,看水還是水。大概技術(shù)領(lǐng)域也同樣如此。
回到一個古老的問題,有人問:如何給一個變量命名,詞窮了怎么辦?專家的回答是,按領(lǐng)域驅(qū)動設(shè)計的方法對變量進(jìn)行命名。這就是實踐領(lǐng)域驅(qū)動設(shè)計的大師高論,已經(jīng)到了看山還是山的地步。而普通開發(fā)者們,總是看了幾篇領(lǐng)域驅(qū)動設(shè)計的文章,就會以為嗯,我遇到的這些問題,用領(lǐng)域驅(qū)動能解決,然后,就陷入一堆概念之中不可自拔。
實踐是檢驗真理的唯一標(biāo)準(zhǔn),唯有真的使用一個項目開始實踐,才能真正體會領(lǐng)域驅(qū)動設(shè)計的精髓。領(lǐng)域驅(qū)動設(shè)計思想,是一種充滿魅力的軟件理論方法,然而要把這套理論真的用起來,依然需要經(jīng)歷一個從新手到高級新手,再到勝任者、精通者和專家的學(xué)習(xí)過程。本文也同樣屬于一位處于新手村學(xué)習(xí)者的個人見解,班門弄斧,期待能拋磚引玉,措辭多有不當(dāng),還望海涵。
參考資料:1、Eric Evans《領(lǐng)域驅(qū)動設(shè)計·軟件核心復(fù)雜性應(yīng)對之道》
? ? 2、張逸 《GitChat講座:領(lǐng)域驅(qū)動設(shè)計實戰(zhàn)》
? ?3、Gojko Adzic《實例化需求》
原文地址:https://www.cnblogs.com/xiyuanMore/p/11049418.html
總結(jié)
以上是生活随笔為你收集整理的领域驱动设计,让程序员心中有码(八)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 是时候挥别 SQL Server 200
- 下一篇: 基于Dapper的开源Lambda扩展,