業務域,是軟體的核心價值所在。
敵人還是朋友:專案經理和架構師
從Repository到Domain
從MVC到測試
從自動化測試到Domain
代碼工廠=CRUD?
敵人還是朋友:專案經理和架構師
無論是買成型的軟體產品,還是出資開發項目,客戶投資的是軟體的業務價值。專案經理直接為這個目標負責,盡量少的成本,盡量短的時間,生產出高業務價值的軟體產品。架構師則是跨越單個項目,長期為這個目標負責。
專案經理與架構師是天生的敵人,短期看這是對的,長期來看,他們是真正的朋友,是戰略朋友。沒有專案經理項目會死得很快;然而沒有架構師,公司會死得很慘。
專案經理的角色和作為,我仍比較容易理解。一則,他以短期為目標,人都是短視的,所以專案經理的角色比較接近人的直覺;二則,專案經理的活動也是我們常見,常說的,例子故事較多。而對架構師,我們卻頗多誤解,至少也是含混不清。
我曾經問過很多開發人員,你的五年計劃是什麼?幾乎無一例外的回答都是想成為一名架構師。特別是在校學生,幾乎是脫口而出。這是一個有意思的現象。我的理解,一、他的職業方向是技術方面,想在技術上有所建樹,架構師是一個明顯的技術標杆,從這一角度,我很肯定他們的回答。二、業界對軟體職業兩條線,項目輕理和架構師,這個理論已經深入人心,也不錯。三、架構師成為脫離“開發苦海"的代名詞,頗值商榷。
架構師不是一個只管"架構"的傢伙,他更是一個集大成者。各種技術,無論高雅還是低俗都是他囊中的武器。還有低俗的技術嗎?有的,非常多連剛入門的開發人員都覺陳舊的好東西。
什麼,繼承,你老土了吧?開口只會說設計模式都不敢說你是做開發的。現在,都是雲,雲開霧照的雲。NoooooSQL一聽這名字就得勁。否定錯誤就是正確,這世上哪有沒有瑕疵的東西。所以,我們的口號就是否定一切!好了,扯太遠了。
是的,架構師的工具箱中應該有琳琅滿目的各種稱手的工具。但這隻是從一個視角看架構。我們很多時候盯這些工具本身盯得太緊。看工具或者技術本身,如何的眩麗、如何的酷斃。今天,我們來換個角度,看看工具和技術的目標,他為誰服務?
從Repository到Domain
首先,倉儲模式(Repository)。Repository不是DAL!雖然它們如此的接近,有的架構設計就把它們合二為一了。Repository用於對象持久化,DAL是從資料庫中操作資料。仍然迷惑,看不出兩者的區別?
讓我們來一個思維的遊戲:
- 一般三層架構的文章用來解釋DAL層的好處,用資料庫的變更做例。比如:之前系統是用ORCAL資料庫,現在要換作SQL Server。如果,我們使用了DAL這一層,就可以很容易實現,而不觸及系統其它。
- 我這裡需要你設想另外一種變更,從資料庫儲存資料,切換到用檔案系統,如CVS或XML檔案放資料(如果你要想的更進階一點,更酷一點,可以想想用雲儲存)。這時候,DAL這一層的隔離已經沒有辦法解決了。而是要更上層,這就是我們的Repository。
所以,可以說Repository和DAL是兩層。自然,這增加了複雜度,你確實需要衡量你系統是否必要。另外,nHibernate可以很好的擔當了DAL的角色,同時對Repository的支援也很好。應用得當,可以減少很多工作量。
再回到Repository的描述,Repository用於對業務域對象持久化。細心的人可以發現,我加了三個字”業務域“。
從MVC到測試
其次,MVC。MVC不是三層架構。雖然看起來它也分三塊,但決對不是。另外,MVC中的M不是業務域,決對不是,雖然有些系統實現採取了這種方式,把MVC的M和業務域對象合二為一,但是原則上它們完全不是一回事。微軟用VM(View Model)代替M還是有點意思的。
MVC最大的目的和功能,是把最終介面相關(V的部分)的東西最大限度的隔離出去,因為這部分是不可測試的,而那些仍然與介面相關,含有大量邏輯(演算法?)的部分抽象出來,或者放入C中,或者放入M中。使得可測試的代碼的邊界,儘可能推到UI的最前沿。雖然,慢慢現有不少UI測試自動化工具的出現,功能還不錯,但是與單元測試,代碼直接介面的測試相比,效率和品質還是不可同語。
仍然回到對目的的思索。MVC是為什嗎?為了測試?恐怕還不是最終的目的,測試又是為了什麼呢?
從自動化測試到Domain
單元測試,行為測試,整合測試, 眾多名詞,我不想討論它們之間的差別,作為一類概念,從名稱上,他們只呈現了一半的內涵。還有一個重要部分被漏掉“自動化”。自動化單元測試, 自動化整合測試,才更為準確。自然,這裡我也不討論非自動化測試,如功能測試,驗收測試。
自動化測試的好處是不言而喻的。前文中MVC提到的測試,就是指提高自動化測試的覆蓋率。對整個系統來說,達到100%的覆蓋率是根本不可能的。在這個大前提下,我們很容易忽略提高自動化測試覆蓋率的重要意義。90%與70%只是數位區別?讓我麼走近一點,把系統拆分一下再看。整個系統不能達到100%,具體是那部分不行呢?前面提到的View是一個,資料庫又是一個,不是完全不能測,理論可以,實際有些麻煩,不值當。還有就是一些外部功能,如發郵件,讀寫檔案。檔案操作這個看來經常用到的功能塊卻是單元測試的大敵。所有這些排除後,再回頭看看,我們可以說剩下的100%能測試,也必須測試,不然就是架構和設計的問題。
剩下的這100%中,很大部分就是業務領域模型,重中之重,難中之難,也是值中的超值。
代碼工廠=CRUD?
前面的Responsitory也好,MVC也好,看似複雜,其實簡單,簡單在於邏輯固定。昨天,我花了一個小時,完成了一個簡單類的添加,現實的功能,從前端controller(我叫command)到服務層,業務類,再到Respository及資料庫,只花了一個小時。因為邏輯簡單固定,相當於一個表的CRUD。很多推廣的所謂一站式解決架構,都是用這種情況的典型案例,特別是微軟,從VB開始,到現在的Entity Framework,最酷的示範就是只要添加幾行資料定義,一分鐘,從介面到後台完成。當然,這比我昨天的手工作業要快得多。但是回到實際的商業軟體開發,從來沒有基於這樣的高效而能一天完成一個項目。不是嗎,如果按一分鐘一個介面或者一個資料表,一個有100個表的項目已經足夠大了吧?這樣簡單做個乘法,我們不是100分鐘就可以搞定了嗎?實際呢,不用說100分鐘,就是100個小時也不夠。所以,這樣的示範根本沒有含義,可是,很多人卻樂此不疲。
我以前公司,有一位架構師,在iBatis的基礎上,完成一個所謂架構,可以已經建立的資料表,自動產生業務對象,和CRUD的代碼。然後驕傲的宣布,80%的開發工作已經完成。可是之後,項目又開發了兩年。如果說是80%的代碼量,我可以說是,80%的工作量?我懷疑。
這正是我們很多架構師沒有意識到,或者不願意承認的事實,架構設計好了,架構搭建好了,這才剛剛是個開頭,而遠遠不是結束。
這是百般武藝亮盡的結束, 是業務領域探險的啟程。
下一篇文章,可能會拿出一個業務領域的經典例子來看看:年月(YearMonth)和時間段(Range)。是否有興趣?