1. 程式人生 > >#原創分享# DDD領域建模之為什麼堅持使用

#原創分享# DDD領域建模之為什麼堅持使用

       閱讀這邊文章的你,可能與我有相同的想法:致力於開發高質量的軟體的同時,降低程式中的bug數量--貌似不存在沒有bug的軟體產品(世界上不存在完美),軟體一直在嘗試模擬人類社會的某種活動,這個模式提前註定了軟體的悲劇----那就是一直在模仿,從未有過超越,一旦軟體無限趨近與人類的實際活動時,人類又會出現更加成熟、簡潔的社會活動。目前暫時無解......所以,設計出能夠精準表達人類活動意圖的軟體模型顯得有為重要了。

    DDD (領域建模)作為一種軟體開發的方法論伴隨者這種呼聲應運而生,很慶幸自己在幾年前就開始解除DDD,並且在大大小小的專案中不斷的理論聯絡實際,隨著系統的複雜度越來越高,越能體會到DDD的強大與優美,基於DDD架構的軟體工程如同一臺設計完備的機器,具備精密的同時還具有一定的擴充套件性,你可以把他想想成為汽車裝置的引擎~~~~等,有些寫不下去了~~~ 正所謂:通過DDD完成的恰恰就是軟體的工作方式,讓軟體不再是冰冷的程式碼,而是注入了一種生命的張力。

     我們的目標是創造一個可測試、可伸縮、可擴充套件、組織良好的軟體模型,通過程式碼在實現其模型,在這個過程中DDD為我們提供戰略與戰術上的全訪為指導,(戰略可理解為軟體的巨集觀層面,戰術則意味者某一些具體的軟體實現本身.....),想到 井上雄彥 的《灌籃高手》年近40歲的我已經熱邪沸騰啊。這些年在努力的堅持與貫徹DDD,最大的感受之一就是可以跳出程式設計師的思維模式,並且可以討論、聆聽、裂解與發現業務專家的業務講解,儘管依然無法擺脫技術的限制,但是可以做到有所側重,至少在需求階段可以聚焦於 使用者如何理解與使用軟體本身,而不考慮其軟體實現。用DDD的術語來講,就是好的軟體團隊是要配置領域專家,這些領域專家會用他們固有的行業術語向你(我們程式設計師)描述業務本身。這裡再討論深一些,搞火箭出生,順道搞搞電動汽車的美國瘋子-特斯拉老闆CEO 馬斯克,這廝思維模式一種與眾不同,常常採用第一思維來思考問題,第一性思維來思考問題,什麼是事物的的第一性,這是一種很不錯的思維模式,大家可以再業務討論的過程中有意識的鍛鍊自己,儘管不一定是正確的,至少再探索事物的道路上,走的也許會比別人更遠一步.......

     好了,還是迴歸我們的DDD吧,領域專家可以幫我們建立更為專業 與 更加接近業務本源的領域模型,所謂領域模型,其實就是特定業務領域的軟體模型,這些領域模型是通過一系列的物件模型構建而成,這些物件不僅僅是資料的持有者,還包括了  行為本身,以及基於行為疊加的複雜業務邏輯,從而敬重的定義與描述了 業務含義本身。 好了 這裡提到了OOP,面向物件程式設計,基於DDD是無法繞開這個關卡的,OOP是構建DDD的最小單元,這時也許會有人產生質疑:不就是OOP嗎?用Hibernate這麼多年了,難道不是OOP? 再這裡,我只能說,Hibernate僅僅解決了OOP資料層持久化的問題,如果更加精確一些,Hibernate所代表的應該是 DTO(資料傳輸模型),如果一定要用DTO認為是OOP,只能說 那是一具沒有靈魂的皮囊,徒有其表而已。理解OOP,選喲時間的積累與沉底..... 也許有一天,你對OOP有一種全新的認知,彷彿一些皆可物件化....恭喜 再OOP的道路上前進了一大步......,如果用DDD的語言來描述呢?DTO模式的物件 定義位 “貧血模型”,想想看,基於貧血模型構建的軟體工程~~~健康度可想而知~~隨時都是搖搖欲醉啊~~~,我可以舉出一些實際的雷子來證明一下所謂的“貧血物件”:

    1、我們再基於OOP程式設計時,所謂OOP是不是主要實現的setter與getter方法呢,而且針對物件自身基本沒有業務邏輯,所謂的業務邏輯都被外放到 service 層

   2、軟體元件是否包含了系統主要的業務邏輯呢?並且多數情況下需要呼叫 setter與getter方法實現,所謂的物件幾乎沒有 建構函式,物件內部沒有什麼的修飾符:例如 final  修飾那些不可變屬性

  3、大部分程式都是用MVC,M層實現setter與getter  ,service層實現所謂的業務邏輯、V層實現對外http服務的釋出?  

   如果上述滿足任何兩條,恭喜你的程式碼基本都是 “貧血”的。。。。看來 Hibernate 等ORM框架對我們影響太深淵了,萬惡的Hibernate.......也許是我對這個框架天然的排斥把,至今我在維護的專案依舊採用這個,期間經歷的種種無奈,也只有我能體會把.....    難道物件沒有自己的行為麼?為什麼把物件該有的行為定義到service中,物件是用來幹嘛呢?難道僅僅是DTO麼? 不要吝惜程式碼了~~~ 讓真正的OP迴歸把~~~ (後面沒獨立章節介紹),例如我們常常炫耀自己寫了一個完成的函式  updateXXXX()  ,這個方法可更新任何資料到資料庫中........ (what a fuck.....),直接寫一個 CRUD 介面得了,一個好的物件,至少要明確那些是不可以變化,那些是可變化的,為什麼會有這樣子的變化,背後的業務邏輯是什麼...為什麼或者這樣子~~是否還有更加好的解決方案.....這才是引入DDD後需要思考的問題.......

     為什麼引入領域專家呢?應為程式設計師與實際業務之間,有一條天塹,我們IT這個行業彷彿可以對接任何一個行業,但實際而言呢?隔行如隔山啊,作為開發者能夠傳遞真正業務價值的軟體模型與開發軟體之間有所差異的,具有真正業務價值的軟體模型能夠更好的符合業務戰略,並且能將更好的競爭優勢融合到解決方案中,而這些業務模型都是與業務相關的 ,好的軟體模型能夠指導、引領業務自身並實現自我進化.......,但是現實中呢?很少能夠遇到或者配合專業的領域專家,就算是軟體需求團隊,也需要再某個行約浸淫N年,業務勉強可以稱其為領域專家.......於此同時,領域專家的重點在於業務本身的交付與使用,我們程式設計師的思維重點是技術如何實現,這種天然的矛盾體,基本可以定性 業務與 技術 天生的冤家~~~~ 這也是軟體行業需要解決的老大難問題~~~而DDD,則強調把領域專家與開發人員聚集到一起,一起討論、分享、構建業務模型,這樣所開發的軟體能夠精準的實現業務本身。

       談到目前呢? 這些都是再討論DDD的引入解決什麼問題,其實,首先解決的是程式設計師如何用業務的思維來理解業務,而不是用技術的思維來理解業務,引入DDD的首要目前是構建 通用語言以及所謂上下文,所謂通用語言不一定是UML,基於某種場景下讓領域專家與程式設計師在業務溝通層面能夠達成一致即可,切記不要犯這樣的錯誤:你以為你以為的就是你以為的嗎?不要自大,要不恥下問,特別是站在我們程式設計師的立場,在業務專家面前,我們都是小白,儘管人家領域專家也許也是個90後的小弟弟或者小妹妹。。。。。。目前按照我的模式可以進行如下的方法:

    1、構建統一的溝通上下文以及專有名詞的定義,這個很要命,常常出現你以為你以為的就是你以為的命題,這方面業務專傢俱有主導權,一千人眼中有一千個哈姆雷特,特使在業務專家眼中,只有唯一的哈姆雷特.........

  2、在第一部的基礎之上 構建統一的術語表,並且文件化,好記性不如爛筆頭啊~~~ 我年齡大了 有些記不住了~~ 好漢不提當年勇,也許當年也沒有勇過

  3、把這些術語進行有效合理分分類,使其在特定的語境下,各自有獨自的專有含義,例如 訂單(術語),在不同的環節上  購物車、下單、郵寄等包含的側重點有所不同.......

  4、上下文字身,就是完成某個具體業務的語境,脫離上下文,專業術語也就沒有意義了

切記,上述的步驟是通用的流程,拋磚引玉,在實際的實踐中,不要拘泥於形式  核實自己的就是最好的~~~ 讓DDD 開始陪伴團隊一起成長把......

 

        一個好的企業應該嘗試使用DDD驅動來推動軟體與業務的發展,如果作為程式設計師的我不在熱衷與技術本身時,需要把眼界放的更加寬廣一些,不管用什麼樣的技術,最終要想使用者提供業務實現的價值,(可惜做不到,至今依舊時Java的粉絲......),嘗試構建領域模型會給軟體團隊以及公司帶來豐厚的回報:

        1、構建立刻一個有用的領域模型,這一點很重要

        2、基於上述的領域模型,業務得到了更加準確與清晰的定義

        3、領域專家可以位軟體設計做出相當大的貢獻,軟體不再時IT的寵兒

        4、為最終的使用者提供更加良好的使用者體驗

        5、更為清晰的模型邊界(這個有些難以理解,慢慢熟悉),DDD 包含的內容很多,OOP、聚合、核心域、值物件、上下文 持久化等,互相協作而產生了邊界以及邊界之間的協助

        6、更加專業可擴充套件的軟體架構以及 敏捷、迭代與持續構建

    

       當然DDD在引入不是沒有門檻的,而是門檻時可變化的,沒有什麼時絕對的,引入DDD也是需要一些代價與覺悟的,如果這點服務都沒有,那麼DDD更多的是紙上談兵......如下的幾點挑戰是無論如何都無法迴避的:

      1、是否為建立領域模型騰出時間與精力(這一點很要命,大多數企業都比較短視,認為軟體就是線性發展 ,從未奢望過 指數級發展,也無法騰出時間各研發與業務進行更加完善與全面的討論)

      2、持續的把領域專家引入專案,伴隨專案的發展一起發展,沒有一個領域專家可以搞定軟體的全部,所以這個也是很重要

      3、程式設計師用領域模型的思維來思維軟體研發

      上述的幾條,基本都花費在軟體前期的論證與討論方案中,當然在其中首先需要一個能夠基於DDD思維模式貫徹的Leader。。。。需要一個方法論的指引.......

       DDD實踐是一個長期的過程,但是總要有第一次的嘗試,不要擔心失敗或者走彎路,良好的DDD可以讓讓軟體更加趨近本身~~~~

       今晚難得~~沒有業務的打擾~~~吃飯至於向寫點什麼來記錄我DDD的實踐之路~~~~ 後續有連載~~~ 時間到了  該給娃洗澡了~~~~人到中年~~身不由己啊~~~~

       DDD是個好東西,它是一套方法論,不是具體的技術,是程式設計師思考這個世界的一種可行性方案,說多了都沒用,實幹才是王道~~~~此情可待成追憶.......

 

 

 

    

 &nb