論壇文章
Domain Model?為什麼?

我小時候成長於雲林的鄉下,雖然不是十分偏僻,但因為人口也不多,因此連郵局都沒有,只有一個代辦所,專門賣郵票並收發掛號信。在我小學五、六年級時,終於開辦郵局了,當時非常興奮,在放寒假或暑假時就很快去開了一個帳戶,記得帳號應該是只有兩位數。那個時候,(1968年左右,人類剛登陸月球),郵局帳戶尚未用電腦處理,提款機更不用說了。存款(或提款)的流程是這樣子的,填了存款單,連同存摺交給辦事員(也兼賣郵票),他會從櫃子中取出一張硬活頁紙,裡面記載的就是我的帳戶所有的交易資料。然後他會同時在我的存摺及交易資料的活頁紙上,登入今天的交易(是的,用手寫),若有其他交易(如利息)也會補登到我的存摺中,當存摺及交易紀錄的活頁紙都登錄完之後,會一起送給坐在後面的局長(當時郵局一共也只有兩個人)複核無誤後再把存摺還我。當我高中在台北念書,也是一樣在郵局開了帳戶,不過時代是進步了一些,用一台類似電動打字機的機器將交易紀錄同時打在存摺及交易紀錄的活頁紙上,至少減少了兩次手寫可能的錯誤。後來研究所畢業後開始工作,因薪水直接入帳銀行,因此在銀行開了帳戶,當時的銀行比較先進一點,存摺是印表機印出來的,表示銀行是使用電腦在處理帳戶資料及交易紀錄。後來出國,到了美國,才第一次見識到提款機,而美國銀行通常都會給你支票簿(記得第一次開支票,還覺得蠻高興的)。不過要再過兩三年後才開始可以使用跨行提款機,而這一切,今日在台灣已是普通常識了。

這一段個人和銀行及郵局打交道的歷史,幾近四十年,雖然方式、流程皆不同,但有一項東西是不變的,即是銀行所處理的帳戶資料及交易紀錄,不管是使用紙本的方式,使用電腦檔案,或是存入資料庫,銀行系統要處理的資料,本質上並沒有太大的改變。另外一個不太改變但又有些變化的是銀行提供的服務,雖然銀行提供服務的方式一直在改變中,如由人工作業到自動提款機到網路銀行,但是其基本服務,卻也沒有太多改變。因此當我們在設計一個系統時,我們應該把系統的基礎建立在哪裡呢?任何人都知道我們不應該把房子蓋在沙灘上,而應該蓋在磐石上,因為盤石不容易改變,所以房子才能恆久矗立。因此我們在設計一個系統時,是不是也需要思考一下,哪些部份比較不會改變,那些部分又是比較容易變動的,然後將我們的基礎建立在不容易變動,比較穩固的基礎上呢?

銀行系統並不是唯一有這種特性的案例,還有許多其他的例子,例如學校的註冊選課系統,從以前的手寫方式,到語音選課到網路選課,而且幾乎每一個學校的流程都不一樣,但是處理的資料大概從五十年前到現在,幾乎都是相同的。

由資料以及資料之間的關係這個角度來看一個資訊系統,其實我們的老前輩們老早就明白這個道理了。相信許多老人們都聽過一個設計方法,Jackson Method,這是寫COBOL程式的人常用的一種方法。他的方法是先將系統要處理的資料架構建立起來,然後再依據資料架構來設計整個系統架構。一般認為以這種方法設計出來的程式比較容易修改,日後也比較容易維護。Jackson Method衍伸出來的Jackson System Development(JSD),某些人認為是第一種物件導向設計方法。另一種以資料為基礎的是大部分熟悉的結構化分析及結構化設計方法(Structured Analysis/Structured Design)。這種方法因採用輸入-處理-輸出(Inputrocess?Output或IPO)的模式,經常被歸屬於功能性(Functional)的設計方法。但是當我們在畫資料流程圖(Data Flow Diagram,DFD)時,一件非常重要的事情是資料只能被轉換,但不能有增刪,也就是資料不能自行產生也不能憑空消失。在此,資料被處理的過程扮演了引導出程式架構的角色,而且在做SA/SD時,第一件要做的事就是建立資料模型(Data Model)。為什麼要從Data Model開始,因為這是最不容易變動的部分,這是老前輩們的智慧結晶,也是痛苦的教訓而得來的。如果我們不能記取前人的教訓,我們必定會重複前人的痛苦。這種痛苦就是系統永遠改不完,永遠在修修補補,永遠穩定不下來。

當我們在設計一個系統時,尤其是一個稍具規模的系統時,一件重要的事情是軟體架構(Software Architerture)的設計,因為軟體架構基本上是訂出軟體系統的各個模組以及模組之間的關係跟互相溝通的方式。軟體架構的設計不僅可以使系統有效的分工,讓不同的人負責不同的模組,而且也是將來系統移轉建置,或是發展成產品的藍圖。雖然軟體架構有可能因為不同的需求,如執行效能的需求,容易維護的需求,安全性的需求,容錯的需求等(這些都是非功能性的需求),而設計出不同的軟體架構,其基礎基本上都是相同的。比較早期的看法,這個基礎是資料模型,比較現代的看法,則是Domain Model。一個基礎,可以有不同的軟體架構,這個道理和蓋房子非常類似。同一個地方,只要有穩固的地基,房子可以蓋成維多利亞式,也可以農莊式,也可以是閩南式。另一個更明顯的例子是101大樓,它不見得要蓋成現在的樣子,但是它的地基基本是不會相差太多的,而且都是需要建立在穩固的基礎上。以一個軟體系統而言,這個穩固的基礎不是流程(Workflow),流程常有變動或合理化,也不是組織圖,因為常會有企業重組,而是一個企業所要處理的資料以及資料之間的關係,或是比較現代的說法,Entity以及Entity之間的關係。

大家耳熟能詳的E-R Model,是一個古典的資料模型,也有人將之視為Domain Model,而實際上也有一些Domain Model的觀念是由E-R Model延伸而來的。許多老人們若是還對以前學資料庫系統的課程還有印象,應該還會記得資料庫系統有三種,階層式(Hierarchical)、網路式(Network)及關連式(Relational),而有些資料庫的書可能也還會稍微回顧這段歷史。當時(1970年代)最多人使用的資料庫系統應該是IBM的IMS,是一個階層式的資料庫。CODASYL,一個業界聯盟,則制定了網路式資料庫(通常即稱為CODASYL)作為標準,而關連式資料庫的概念,則剛出現在學術論文中,屬於叫好但不知叫不叫座的階段。在這種情況下,我們要如何設計一個資料庫來支援我們的應用系統?最好的方法通常是先不決定使用哪一種資料庫以保持彈性(更可憐的情形是可能必須使用兩種以上的資料庫系統),因此我們需要一種不依賴特定資料庫的資料描述方法,而E-R Model就是這樣的一個方法。所以E-R Model在被提出來時,在其論文中,一項重要的闡述是將E-R Model對應到不同的資料庫系統,包括現在大家都在用的關聯式資料庫。所以這裡一個很重要,但是很多人都常犯的錯誤觀念是將Table Schema當成Data Model,這是大錯特錯的事。因此必須在此特別強調E-R Model才是Data Model,而Table Schema則是它的一個實作。由於這樣子的錯誤觀念,因此很多時候,當處理的資料或之間的關係有所改變時,即Data Model有所改變時,常常就不會正本清源,從E-R Model調整,而只在Table Schema上作欄位的增修,或拼命套Query,套Store Procedure,導致程式大幅度修改,造成專案的延遲,這就好像房子蓋了一半又重新挖地基一樣。另一個誤將Table Schema當成Data Model所造成的問題是,當資料庫的型態不再是關連式時,如改為被視為未來之星的XMLDB,這些Table Schema其實就不再適用了。但是原先建立的Data Model在大多數情況下都還是成立的,而且可以透過不同的機制轉換成相對應的資料庫Schema。因此在設計Table Schema之前,一定要先想想這個系統的Data Model長成什麼樣子。

那什麼又是Domain Model呢?一個Domain Modeling所要描述的是Domain中Entities以及Entities之間的關係。一個Entity通常不只包括有資訊(即屬性部分),同時也可以有行為(Behavior)或動作,簡單的說,可以將一個Entity看成一個物件。因此,若是使用UML,通常Domain Model可以用Class Diagram或Object Diagram來描述。因為Entity有行為,彼此之間的關係就會變的比較多樣。有許多時候也會將Domain Model稱之為Conceptual Model,如此事情就變得有些複雜了。有許多軟體工程的書,尤其是物件導向方面或UML相關的書,常常都會說要建Conceptual Model,但是事實上要能真正體會什麼是Conceptual Model,的確需要經驗及智慧。記得以前在寫博士論文時,因為題目是關於物件導向以及需求規格(Requirement Specification)方面,所以對於Conceptual Model、Domain Model這些名詞,當然是琅琅上口,但現在回想起來,當初其實並不是真正體會其真諦的。要能真正了解這個問題,我們就必須知道在軟體工程中,或者是在CMMI中,所產生的各項工程類的文件之間的關係。我們在一個專案中,為什麼要產出一堆文件,如需求文件、系統規格書、系統設計文件以及最終的程式碼。我們產生這些文件的目的不是為了符合CMMI的規範,而是要讓不同的人以不同的觀點不同的角度來看同一件東西,這件東西就是我們最終完成的系統。如果一份文件不是為了這個目的而存在的話,那一個文件基本上是無意義的(因此,專案中最笨的一件事就是補文件)。這就好像我們再看一棟建築物,我們可能會在遠處看,在近處看,進去建築物內部看,或更進一步,進去每一個房間看,這些不同的觀看方式,正是不同文件所要提供的。而Conceptual Model正是提供我們對一棟建築物比較抽象比較直覺的看法,這有點像建築物的模型或建案的樣品屋,主要是要讓你感覺一下系統會長成什麼樣子。

當我們在一個應用領域中,不管你承接開發了多少個專案,做過多少個產品,如果你無法對此領域定義出一個Domain Model,或是更卑微的要求,一個像樣的Data Model,老實說,你對這個領域其實還是不了解的,還是陌生的,你也就沒有資格說你是這個領域的專家,你以前在專案中的努力,都只是苦工,或是使用更抱歉的說法,只是虛工而已。