從混亂到混亂,業(yè)務邏輯搬家記
1.業(yè)務邏輯同學
業(yè)務邏輯同學經常被大家戲稱是業(yè)務中最不講邏輯的東西, 這句話道出了他的本質。
這家伙不僅善變,而且特別喜歡和程序員作對,尤其喜歡制造混亂,讓程序員懼怕他。
他最早棲息在像ASP 和 JSP這樣的頁面當中,整天和那些負責界面展示的HTML,CSS們廝混,在這里除了展示邏輯之外,你還能看訪問數據庫的代碼, 他們堅定不移地以制造混亂為己任,齊心協力把頁面搞得一團糟。
當程序員想去修改的時候就發(fā)現, 這種代碼簡直就是“意大利面條”, 極難閱讀,極難維護。 更不用提什么代碼的復用了。
每當程序員抱怨的時候, 業(yè)務邏輯說: “怪我咯? 還不是你們自己惹的禍!”
2 ***次搬家
時間久了,大家都受不了, 只好想了新的辦法, 分層! 強迫業(yè)務邏輯和展示邏輯分家 !
業(yè)務邏輯被迫搬了家,再也無法和展示層的HTML,CSS一起喝酒吃肉, 每次想聊個天還必須得通過特定接口, 把數據發(fā)給展示層才行。 比如業(yè)務邏輯層會發(fā)個View Object 給展示層,把自己的孤獨和思念捎帶過去。 再后來展示層完全從服務器端移到了瀏覽器端,業(yè)務邏輯想打個招呼就得跨越網絡的千山萬水了。
業(yè)務邏輯退而求其次, 和Java bean 打得火熱,不過很快就發(fā)現和Java bean 實在沒什么好聊的,太單純,沒有一點深度,除了getter/setter方法之外,啥都沒有。
有人把此時的業(yè)務邏輯稱為Service , 有人稱為Manager ,業(yè)務邏輯更喜歡這個名字,因為顯得更加威嚴,更像系統的老大。
無論叫什么,其實做的事情都是一樣的: 根據隔壁房間或千里之外的展示層傳過來的指示, 從數據庫讀取數據,形成java bean(有時候連java bean 都不需要) , 進行業(yè)務邏輯運算,再給展示層發(fā)送結果。
程序員把這種Java bean 形象地稱為貧血模型, 因為它一點業(yè)務邏輯都沒有, 業(yè)務邏輯在Service中放著呢。
這種簡單的開發(fā)方式受到了廣大程序員的歡迎,它概念簡單,門檻極低,初學者很快就能掌握。
建個數據庫表, 創(chuàng)建一個對應的java 類,使用Hibernate, MyBatis把它映射到數據庫表和字段上, 接下來就可以在Service 中隨心所欲地操作這些Java bean 實現業(yè)務邏輯了,完全不用什么“高深的”面向對象的分析和設計 。
一個項目劃分成多個模塊, 大家都按照這種模式開發(fā), 再加上一些輔助的開發(fā)工具,能夠自動化從數據庫表生成各種類, 實在是直接而酸爽。
一大批使用貧血模型的應用程序如雨后春筍般地出現,慢慢地變成了趨勢,好像用Java做面向對象的Web開發(fā)就是這個樣子。 尤其是后來維護項目的程序員, 更是覺得天經地義。
(碼農翻身老劉注: 按照Martin Flower在《企業(yè)應用架構模式》中的定義,這種方式叫做事務腳本,其本質是用面向對象的語言寫面向過程的程序)
這種模式對于簡單的增刪改查一點問題都沒有,甚至還有優(yōu)勢 !
業(yè)務邏輯這家伙經常在誘惑程序員,來啊來啊,再多給我的Service/Manager加點邏輯。
隨著系統越來越復雜, 這家伙得逞了, 大量的業(yè)務規(guī)則被添加到Service 當中,Service越來越臃腫, 開始變成巨無霸的類, 各種狀態(tài)、判斷、if else 交織在一起, 喜歡混亂的業(yè)務邏輯同學又激動起來, 又回到了“面條代碼”的“美好”時代。
3 第二次搬家
程序員們決定再次讓業(yè)務邏輯搬家, 搬到一個清靜的地方去。
有一天,有個叫做Eric Evans的大神提出了一個新方案: 把Service 層和領域層分開。
(碼農翻身老劉注: 在Eric Evans的領域驅動開發(fā)中,最下面是基礎設施層,而不僅僅是數據訪問, 我這里為了和之前的圖保持一致,只把數據訪問列了出來)
業(yè)務邏輯同學很不爽地發(fā)現,自己不但和展示層徹底說byebye ,還被拆分到一個個的領域對象當中去了,這些對象不僅僅是具有getter/setter的java bean , 而且擁有相關的業(yè)務邏輯、業(yè)務狀態(tài)、業(yè)務規(guī)則。 現在各個領域對象要想聊天吹牛,也非得調用相應的業(yè)務接口才可以。
原來的Service 層也成功減肥,變得非常輕薄,不再包含業(yè)務規(guī)則和知識,只是為下層的領域對象協調任務,分配工作,指揮著他們完成業(yè)務任務,解決問題。
程序員們被美好的前景激勵著, 努力地幫著業(yè)務邏輯再次搬家。 喜歡混亂的業(yè)務邏輯同學這次要絕望了, 以后的系統都這么搞,自己還有什么活路。
可是沒想到這一次搬家難度很高, 尤其是從需求中分析合適的領域對象,實在不是一件輕松的事情,習慣了之前那種用數據庫表驅動的開發(fā)方式,想轉到領域模型驅動的開發(fā)方式, 讓大家很不適應。
于是業(yè)務邏輯同學趁勢鼓噪,算了吧,這種方法太難了,你有豐富的開發(fā)經驗嗎?、你有優(yōu)秀的面向對象設計能力嗎?你能把業(yè)務領域專家拉進來一起討論設計嗎? 不行吧? 還是退回去吧,貧血模型多好,又簡單又熟悉。
這廝還真得逞了,鑒于大部分遺留系統都是貧血模型,大家沒有勇氣更沒有時間去重構,只好將就著繼續(xù)往混亂的Service舔磚加瓦,希望能熬到系統重寫的那一天。
業(yè)務邏輯再次搬回到熟悉的地方,再次開始幸福的生活。
【本文為51CTO專欄作者“劉欣”的原創(chuàng)稿件,轉載請通過作者微信公眾號coderising獲取授權】