面向對象建模與數據庫建模兩種分析設計方法的比較

板橋里人 http://www.jdon.com 2007/9/23(轉載請保留)

 

我們知道:一個軟件從無到有需要經過如下幾個階段:分析、設計、編程、調試、部署和運行。

   編程階段我們通常使用Java/.NET這樣面嚮對象語言工具,可以帶來很多設計上的好處,但是也存在一個奇怪的現象:
很多程序員雖然在使用OO語言,但是卻在code非OO的代碼,最終導致系統性能降低或失敗,這個現象在Java語言尤其
顯得突出,難怪有些人就把問題歸結於Java語言本身,睡不着覺怪牀歪,又爲了面子問題,說自己轉向.NET,實際上是在 迴避自己的問題和弱點。

  那麼,這些人的問題和弱點體現在什麼地方呢?從上面軟件生產過程來看,每個階段都對前面有所依賴, 在編程階段出問題,追根溯源,問題無疑出在分析和設計階段,分析設計作爲一個軟件產生的龍頭,有着映射實際需求世界 到計算機世界這樣一個拷貝任務,如何做到拷貝不走樣,是衡量映射方法好壞與否的主要判斷標準。

  目前,將需求從客觀現實世界映射到計算機軟件世界主要有兩種方式:傳統數據庫分析設計和麪向對象建模( object-oriented class model), 當前軟件主要潮流無疑是面向對象佔據主流,雖然它可能不是唯一最好最簡單的解決方案,但是它是最普通,也是最恰當的。

  也就是說:在分析設計階段,採取圍繞什麼爲核心(是對象還是數據表爲核心)的分析方法決定了後面編碼階段的編程特點,如果以數據表爲核心進行分析設計, 也就是根據需求首先得到數據表名和字段,然後培訓程序員學會SQL語句如何操作這些數據表,那麼程序員爲實現數據表的前後順序操作, 必然會將代碼寫成過程式的風格。

  相反,如果分析設計首先根據需求得出對象模型(class Model),那麼程序員使用對象語言,再加上框架輔助,就很順理成章走上OO編程風格。 至於OO代碼相比傳統過程編碼的好處不是本文重點,可參考J道(jdon.com)相關討論,擴展性和維護性好,開發越深入開發速度越快無疑是OO系統主要優點。

  本文重點主要是比較OO建模和數據表建模兩者特點,這兩者我們已經發現屬於兩個不同方向,也就是說,屬於兩個完全不同的領域,在J道其他文章裏我們 其實已經把這兩個領域上升爲不同的學科,數據表建模屬於數學範疇思維;而OO建模屬於哲學思維。(用科學的思維方法指導軟件的設計開發 http://www.jdon.com/article/32520.html

  下面我們看看面向對象的Class Model和Database Model是如何來表達客觀世界的,也就是他們在表達需求上有些什麼不同?

面向對象模型(Class Model)

  類代表一個對象類型,類在代碼運行階段將被創建爲一個個對象實例, 每個類由兩個部分組成:屬性和行爲,屬性通常是一些數據狀態值,也就是說:類將數據封裝隱藏在自己內部了, 訪問這些數據屬性必須通過類公開的方法,或者接口。

  別小看這樣一個小小包裝,卻決定了以後代碼的維護性和擴展性, 打個比喻,日常生活中我們經常用各種盒子和袋子包裝一些東西,這樣做就是爲了方便這些東西的攜帶或儲藏,小到生活, 大到客觀世界每個地方,都是包裝分類的影子,無論大小公司都是一個封裝,行政部分單位劃分,倉庫物流更需要包裝, 我們從來不會因爲嫌麻煩而不願意引入一個似乎多餘的盒子或袋子,那麼有什麼理由不在我們賴之生存的軟件中(靠編軟件吃飯) 引入封裝概念呢?

  這裏可以再深入想像一下:不願意用盒子和袋子的攜帶東西大部分是一些急脾氣的毛頭小夥子,而偏偏這些小夥子又從事 軟件工作,看來軟件的非對象化是註定的,只是一個玩笑。

  類的方法行爲也有多種類型,如公開 私有等,我們可以設計一些方法爲公開接口,而將另外一些行爲隱藏起來, 這樣一個看似簡單靈活的選擇,卻能夠應付我們日後頻繁的修改,軟件不修改就不叫軟件,軟件修改了就崩潰是業務軟件, 專業的軟件是抗修改的,而且能夠極其方便快速地被修改。這些都依靠接口公開和隱藏這樣一個簡單魔術,具體各種魔術表演 可以參考GoF設計模式(http://www.jdon.com/designpatterns/index.htm)。

類的關係
  我們不能只用一個一個單獨的類來表達客觀世界,因爲客觀世界存在千絲萬縷的各種關係,在計算機領域無疑我們使用 類的關係來表達映射這些關係。這裏我們只探討類在建模方法上的關係,而不是UML中類的通用關係。 類在建模上主要有如下幾個關係:

  類與類關係經常是這樣:一個類包含一個類(構造性structural),或者藉助另外一個類達到某個功能(功能性), 在對需求建模分析中,構造性的這種關係,也稱爲關聯(Association)是我們關注重點,當然這種關係很顯然表達的是一種 靜態的結構,比如電腦包含屏幕,他們之間的關係就是一種關聯。

  聚合(Aggregation)是一種表格式樣的關聯,表示一個類包含多項子類,這種關係是一種整體與部分的關係。 一個汽車有四個輪子,四個輪子是汽車的部分。

  組成(Composition)是一種更強烈的聚合關係,一個對象實際是由其子對象組成,子對象也唯一屬於父對象。

  繼承也是類建模中經常用到的關係,繼承可以將一些數據屬性抽象到父類中,避免重複,如入庫單和出庫單有 很多屬性是差不多的,唯一不動的就是入庫和出庫的行爲,那麼我們可以抽象一個庫單爲父類,使用繼承關係分別 表達入庫單和出庫單。

  在Evans DDD中,提到通過訪問聚合根來遍歷導航關聯對象,這樣做的好處很明顯保證了對象的從屬性,非常符合 我們日常生活邏輯,比如,你要得到盒子裏面的東西,必須首先得到盒子,然後經過一些準備如打開盒子,才能得到 盒子裏面的東西,假設一下,如果沒有這樣封裝導航關係,盒子和東西都是可以透明並行得到,你想得到東西就能夠 直接獲得,而不必經過打開盒子這一關,這樣的訪問方式首先怪誕,其次是不安全,如果盒子和東西放在數據表中,就會發生 這種情況。

數據庫模型(Database Model 傳統E-R模型 )

  好了,下面我們談論關係數據表模型,以前我們樸素的分析設計都是根據需求直接建立數據表的方式來進行的,爲什麼稱爲樸素, 是因爲我們好像只有數據結構 算法方面的知識,也認爲只有這樣做才叫做軟件。 那麼既然這條路能夠走出來,我們看看這個領域是如何映射客觀世界的。

  數據表由於技術提供龐大數據存儲和可靠的數據訪問,正在不斷從技術領域走向社會領域,很多不懂計算機的人 也知道需要建立數據庫來管理一些事務,但是不代表我們就必須圍繞數據庫的分析設計。

  數據表是類似前面的“類”,也是一種表達客觀世界的基本單元,表有多列字段,表的字段是保存數據的,每個字段有數據類型。 注意,這裏沒有數據的封裝和公開,表的字段是赤裸的,只要有數據庫訪問權限,任何人都可以訪問,沒有結構層次關係, 都是扁平並列的,如果你想在數據表字段之間試圖看出客觀世界中的層次和封裝,那就錯了,在拷貝不走樣這個條件下, 這個映射方法至少把這個信息拷貝丟了。

  數據表也有一些行爲,這些行爲是基於實體的一些規則:

  約束(Constraints) 能夠保證不同表字段之間的關係完整安全性,保證數據庫的數據安全。

  觸發器(Triggers)提供了實體在修改 新增和刪除之前或之後的一些附加行爲,

  存儲過程(Database stored procedures)提供數據專有的腳本性語言,存儲過程象一個數學公式雖然具有抽象簡潔美學,但是這種簡潔是悶葫蘆美學,不是大衆美學,只有公式存儲過程發明者自己瞭解精通,別人無法插手,軟件不是科學,不是比誰智商高,科研水平高,軟件是人機工程,更講究集體,講究別人是否方便與你協同擴展軟件。

  關係數據表的遍歷訪問是通過列字段遍歷或表join等方式實現,SQL語句是這樣標準語言, 只要會寫SQL語句,就能訪問那些失去層次,失去客觀世界特徵的蒼白的數據,這樣的系統能夠多少真實 反映客觀需求,是有問號的?SQL語句是否方便修改,是否經得起頻繁修改而不出錯,都是有疑問的地方,是否 SQL語句越複雜,修改越快,或者另外一個程序員能夠很快修改不是自己寫的SQL語句,這些都是問題所在。

數據表關係

  數據表的關係主要是通過外健或專門關聯表來表達的,這種關係雖然可以反映1:1或1:N這樣關係,但是無法 表達關係的性質,是緊密組成關係式的關聯,還是無關緊要的普通關係,正因爲如此,使用數據表分析設計時, 我們會有蜘蛛網的關係表,這些關係由於在後期無法分辨性質,無法進行整理,增加了系統複雜性。

  更重要的是:分析就是對一個可能陌生領域進行探尋,如果使用數據表的分析設計方法,那麼我們實際就是 在陌生領域中尋找數據表這樣一個形式,那麼有可能產生誤判斷,將一個實則是表達關係的東東誤認爲是一個實體表, 因爲關係表必然帶來關係,這樣,就必然產生蜘蛛網式的數據表模型,將簡單問題複雜化。

總結
  要談方法,這個世界其實只存在兩種:一是將複雜問題簡單化的方法;一個是將簡單問題複雜化的方法。 你使用什麼樣的方法,你就有什麼樣的世界觀,就是什麼樣的人,但是對於軟件這個領域,你只能選擇前者。

  因爲方法的不同,軟件路線也就存在下面幾個路線:完全面向對象類建模路線(J道網站和筆者一直致力於這種路線的推介); 一種是對象和關係數據庫混合型,還有一種就是過去的完全關係數據庫類型軟件(如Foxpro/VB/Delphi等)。需要參考完全面向對象類建模路線的源碼可見http://www.jdon.com/jdonframework/app.htm#simple。

發佈了45 篇原創文章 · 獲贊 0 · 訪問量 7237
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章