面向對象系統設計經驗談

轉載自盧彥的Blog http://www.agilelabs.cn/
 
面向對象系統設計經驗談
 
就像我在應用架構設計總結這篇BLOG中提到的那樣,面向對象的系統設計就好象一羣人翻越一座陡峭的懸崖,只要任何一個人沒有翻越過去,那麼就無法設計出真正的面向對象系統。
 
歸結一下,在你打算進行面向對象的系統之前,你一定要考慮是否已經解決或能解決以下的問題:
 
一、對象的持久化
對象的持久化是最容易被想到的問題,同時也是最難解決的問題。由於關係型數據庫模型和麪向對象模型存在一些比較大的差異,如何將你的對象保存和快速的查詢出來很是頭痛。雖然採用面向對象數據庫雖然可以最方便的解決這個問題,但是你會面臨更多其它的問題,比如備份,報表和實施維護人員的培訓等等。雖然有像NHibernate這樣的ORM框架來幫助你做這個工作,不過你需要去多學習一門資料不全的新技術。另外,這些開源產品中有不少的BUG,你必須有做好調試別人代碼的準備,如果你無法完全掌握這些代碼的話,你會死得很慘。
如果你採用了面向對象來設計領域模型,又沒有找到將對象直接關係化到你的數據庫中的辦法的話,最好不要採用面向對象的設計。否則你會被手工的ORM折磨瘋的。比較好的選擇是用強類型的DataSet,配合VS.NET的數據嚮導工具,非常快。(很有道理)
 
二、界面顯示
由於界面無法直接的將複雜的對象顯示出來,你在界面層又必須再做一次對象的平面化操作,將對象變成各種列表和文本框控件可以直接綁定的一維或二維數據結構。這方面目前還沒有什麼好的自動化方案,你必須手工做。所以我們的策略就是儘量減少這個轉換步驟,就是在服務端就把面向對象轉換成平面數據,然後在客戶端直接綁定到控件上。在數據傳輸對象的選擇上,可以用自定義對象,也可以用DataTable做傳輸對象,兩者區別不是很大,各有各的好處。但是考慮到DataTable可以有一些綁定方面的優勢和VS.Net的調試方面的支持,我們選擇了DataTable。
如果你的對象是手工持久化的話,你做到這一步會感到很沮喪。因爲平面的數據被你費了老大勁從數據庫中轉爲對象,還沒有怎麼體會到面向對象的好處,又要再將對象還原成平面數據交給界面去顯示,你可能會覺得非常的不值得。不如直接就把平面數據讀出來交給界面去顯示,既簡單又方便。如果你已經產生了這個念頭的話,恭喜你,你已經離全面放棄面向對象系統設計,完全退回到面向過程不遠了。(再次暴露了ORM存在的一些問題,從數據庫取回的DataSet轉成Object集合後,到UI又得進行轉化後與控件綁定,特別是CS應用)
 
三、遠程調用
如果前面你還能堅持下來,到了這一步,很少人再能堅持了。面向對象對遠程訪問的問題考慮不足,使用面向對象開發系統的一個最大的優點是建模能力強,業務模型很清晰。比如你要找某個用戶的公司名稱,你可以簡單的用User.Company.Name來得到該用戶所屬公司的名稱。假如你用了多層結構,那麼問題來了,你的對象是建在n層上的,而你需要在n+1層裏對對象進行操作。而且n層和n+1層是遠程調用。那麼,如果你傳個User過去,很明顯用User.Company.Name是獲取不到公司信息的。所以,如果你打算在n+1層做業務邏輯的話,你必須把整個對象樹傳遞過去,這樣做明顯代價又太高。很多面向對象專業人士就提出了什麼VO,BO,DTO,PO等等五花八門的貧血對象來企圖解決這個問題,這樣做的結果不僅是把問題給搞複雜化,更糟糕的是,這樣一來,你當初所憧憬的面向對象系統其實已經是一個變相的Action Script系統了。
所以最好的方式是你就在領域模型層把業務處理完,中間層不要採用什麼分佈式系統設計。Martin Fowler說過:“分佈式系統設計的第一原則是,不要使用分佈式系統”。不知道有多少人能理解這句話的含義。
AF在解決這個問題上也提供了很大的幫助,我們利用了AF創造的統一編程模型,將邏輯儘量都放到領域層裏。從而可以讓更多的操作直接利用到領域模型的完全面向對象的業務邏輯處理的好處。
 
四、開發人員的面向對象思維
這一點最重要,如果開發人員無法認識到面向對象的好處,並且在思維模式上有很頑固的面向過程套路的話。在面對上述問題的時候會抱怨連連,不會盡全力的配合。如果整個的意見無法達成一致,那什麼東西都做不出來,因爲團結纔是最重要的。所以你要麼盡力說服你的團員,讓他們真正的明白並理解爲什麼要這麼做,要麼你就趁早放棄。
最後一條建議:
要麼就完全用面向對象的概念去設計,要麼就完全用面向過程。如果當初是決定要走面向對象的道路,後來又在關鍵性問題上向面向過程做妥協。那麼就乾脆完全用面向過程的思維去解決問題比較好。否則面對一個四不象的怪物,你會發現維護起來更加麻煩。
翻越面向對象這座大山非常艱辛,但是你如果真正能翻越過去,你會發現面向對象的世界真的是一個很美妙的境界。
 
系統分層經驗談
 
爲了將業務規則從界面和數據庫中剝離出來,通常的做法是抽象出一個業務邏輯層出來,專門負責對業務邏輯進行處理。一般多采用三層結構,既表現層,業務層和數據層。
 
當開發人員在以前的兩層結構中痛苦煎熬了很長一段時間,突然看到了三層結構的解決方案的時候,一般會有終於找到了救世主的感覺。但是這種感覺往往會導致掉到另外一個同樣恐怖的陷阱“過度設計”中。在我以前曾經供職的一家公司,以前都是把SQL語句直接寫在ASPX頁面的,後來在讀到了一些關於多層結構方面的資料之後,一下子又把整個系統分成了:表現層(ASPX)、接口外觀層(IF),業務外觀層(BF),數據訪問外觀層(DAF),數據訪問層(DA)和數據訪問組件(SQLHelper)。但是我並沒有吸取教訓,導致後來也犯了同樣的錯誤。
 
犯錯誤的原因有很多,不過主要是因爲沒有一個比較明確的如何分層的指導性原則。假如說我們分層的原則是爲了抽象邏輯,分三層的原因是要讓業務邏輯和界面及數據庫解除耦合,那麼如果按照這個分層原則,我把邏輯重新歸類更加細的分爲四層、五層、六層行不行呢?如果不行,那是什麼原因不行呢?在沒有正確的原則指導下,分層技巧很容易被濫用,導致分出許多沒有必要的層出來。無端的增加了開發和維護成本,以及更重要的是增加了重構的代價,降低了團隊的敏捷能力。
 
面向對象架構設計大師Martin Fowler在介紹如何設計分佈式系統的時候曾說過:分佈式系統的設計原則的第一條是,不要使用分佈式。他的意思當然不是說要絕對禁止使用分佈式設計,而是勸導人們儘量把問題簡單化。能不分佈式設計的,就不要分佈式設計。
我套用他的這句話提出我對分層的感受就是:多層結構系統的設計原則第一條是,不要使用多層結構。(增加相關分層一定要有明確的作用和存在的意義)
 
當然我的意思也並不是說層數越少就越好,而是希望你能清醒的認識到增加層數會增加結構的複雜性,不要輕易的作出分層的決定,一定要到感覺必須要增加一層才能解決問題的時候,再來決定增加一層。
 
過多的層次除了會給系統帶來不必要的複雜性外,還會影響你的系統結構設計。如果你打算採用面向對象的領域模型來設計系統的話,在業務系統內的分層會給面向對象系統的設計帶來很多麻煩,會很容易走回到事務腳本的老路上去。關於這一點,我在面向對象系統設計經驗談這篇BLOG裏詳細的談到過,這裏就不再贅述。
 
下圖是我們最終定型的應用系統結構層次:
   5396D0B24E3E5837012F66297B7A92E5.jpg
 
總結一下:
建立一個完全面向對象建模的領域模型層,讓這個層儘量處理多的業務邏輯。其它層儘可能的薄一點,把業務邏輯都轉移到領域模型層中。

UI儘可能和領域模型貼近一點,中間不要經過太多中轉,物理邊界也儘可能的少。
業務對象只能有一套,也就是領域模型。只要出了領域模型層,外面全部是零散數據,沒有對象的概念。
只有在領域模型層纔可以處理對象。
如果一定要分佈式。全部用簡單數據類型通過接口訪問領域模型。
這個分層結構其實是經歷了多次精簡完成的,所有的感觸都歸結爲一句話:不要過度設計,簡單就是美。
本文爲人月神話博客原創文章,轉載請務必註明出處。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章