2009年1月24日 星期六

為Database-Centric Architecture平反 Part 2

誰才是捉得到耗子的好貓?

在Open Source領域中,Java跟PHP兩項技術都非常活躍。不過兩者的方向似乎不一樣。Java感覺上較擅長於MiddleWare與Framework的創新與精進,而PHP則有許多成功的應用軟體。Java有非常優秀的OR Mapping工具如Hibernate,MVC framework如Struts, Webwork,還有Spring、Wicket、iBatis、Sun自己推的EJB等等,真是百花齊放。但是你如果要找Open Source的討論區、Blog、內容管理系統、或是Wiki等應用系統,就是PHP的選擇多而且活躍。像是phpBB, 維基百科的引擎MediaWiki, XOOPS, JOOMLA等。

如果進一步觀察這個現象,又會開始令人覺得耐人尋味。PHP這些活躍的計畫,常常沒有用太複雜先進的架構,往往就是把『組合SQL指令的程式碼』跟『頁面』寫在一起。MediaWiki就自己說他們的程式碼又複雜又髒。但是維基百科用的正是MediaWiki這套軟體呀!想像它的資料量與瀏覽及更新人次。誰說MediaWiki是不好的軟體?而Java有那麼多優雅的架構與工具做基礎,照理說更容易做出好的應用軟體才對。但是這麼多年來,為甚麼應用軟體仍然是PHP的天下?Java雖然開始有些較具規模Open Source應用軟體,但是仍主要活躍於Middle與Framework。為甚麼在Java族群眼中算是土法煉鋼的程式架構,可以開發出像MediaWiki那麼複雜,同時那麼多人使用的優秀軟體?

Java和PHP大約都是從1995年開始快速發展,兩者的歷史差不多一樣久。投入Java的開發人員也不比PHP要少。如果前幾年Java打下這些良好的基礎,照常理推斷,這幾年我們應該看到很多如討論區等應用軟體的計畫,乘著架構的優勢,快速發展與崛起才對。這個趨勢至今似乎仍不明顯。為甚麼會這樣呢?

原因也許很多。例如,我拿Open Source來取樣很可能有問題,也許Java族群開發應用軟體非常成功,只是恰巧少有Open Source的計畫而已。

它是助益還是負擔?要視情況而定。

不過我個人對這個現象的解釋,是純技術的。前一篇Part 1有提到,討論區、Blog、內容管理系統、Wiki之類系統,重點在於資料的保存與呈現,資料所牽涉的商業邏輯並不多。這種系統非常適合DB Centric架構。即使程式碼的架構不是MVC,不是3 tier,甚至不把頁面與邏輯分開;只要是將系統中心放在資料庫,就受到『關聯性資料庫』這個偉大技術的庇蔭,整個開發難度可以簡化很多。反之,如果引進了中間層,只將資料庫視為儲存位置,很多工作就要自己用程式處理了。

這個概念很重要,值得在這裡用實例詳細分析。以討論區的文章(post)為例,一個post背後可以直接用資料庫簡單的SQL存取來達成,最多牽涉到LOB欄位,稍微要做點小變化。另一派的作法是,建立一個Post class,資料存進資料庫的邏輯再另外處理。雖然我們有OR Mapping的工具,不用自己手寫SQL指令,我們還是要自己建DB Table,還是要設定欄位的對應。還是要考慮LOB存取的方法,還是得注意這兩個效能問題:
1. 要設計好lazy loading的機制,免得隨便做個查詢,找出一百篇文章,就連那一百篇文章的附檔都load進記憶體。(附檔常常是很大的!)
2. 要注意SQL執行的頻率。有時你只是要查個一個簡單的列表,OR Mapping工具在背後偷偷下了幾百個select指令。
即使有這麼多好工具幫忙,開發這支程式真的會比用DB Centric容易嗎?增加了這些複雜度以後,真的未來比較好維護嗎?這要看這個討論區軟體的邏輯是不是真有那麼複雜,需要引進物件技術了。如果邏輯不夠複雜,這派開發方法的優點就無法填補因為放棄DB Centric架構所帶來的損失。所以討論區軟體很適合用DB Centric架構開發,他們不是在土法煉鋼。

反過來,如果要處理的是複雜的商業邏輯,例如公司的組織架構是可以在系統執行期變動,還留下歷史紀錄;或是要處理很複雜的計費規則,費用還牽涉到各國貨幣與匯率計算,我相信DB Centric架構就可能會遭遇到限制。即使SQL寫出來也不容易讓人了解。物件模型可以更優雅地處理複雜邏輯。

要證明一個技術很優越,就舉這個技術擅長的領域做實例

最後,以我常提到的幾本Agile方法或是OO方法的書來做個佐證。Kent Beck的Test-Driven Development前半是在講可以處理多種幣值的Money class(複雜邏輯),後半本是在講xUnit(不是資料處理)。Fowler的Refactoring書中第一章的範例(錄影帶租售),以及因為太長而刪掉,改放到網路上的第十五章的冗長的實例(電費計算),都是處理複雜的商業邏輯。Mugridge/Cunningham的Fit for Developing Software主要是處理出租品的計價規則(複雜邏輯)。Analysis Patterns整本書講的都是我先前從未見過,也未曾想像過的複雜規則(醫院與銀行系統為主)。以上那些書之所以有說服力,其中一個關鍵是只用那個技術擅長的問題來舉例。這類範例下應用這些技術都顯得自然而優美。如果是舉資料儲存與顯示的系統為例,這些書要怎麼寫呢?

另外有一個反面的例子,是Sun當年的J2EE經典範例:PetStore。這是J2EE早期的一個示範性架構。裡面涵蓋EJB、以及其他各種Architectural Pattern的應用。看起來洋洋灑灑,很有結構、很專業、很壯觀,推出後讓只會傳統架構開發的許多開發者有自慚形穢的感覺。乘著當時的Patterns運動風潮,Sun出了一本書叫做J2EE Patterns說明這個架構。還告訴我們一個開發團隊應該有六種角色做專業分工等等新鮮的觀念。不過最大問題是,PetStore這個寵物店範例主要是一般的增刪改查功能。照理說裡面大多動作只要一個簡單的SQL就可以達成。這個架構以那個時代的標準看起來雖然了不起,不過以普通的中小型系統而言,實在說不出比當時主流的DB Centric架構多帶來什麼實際的好處,卻明顯地複雜好幾倍。快十年了,今天回頭看EJB的失敗(我個人就曾是這場失敗戰役的砲灰。),可能應歸咎於現實世界的專案不夠複雜,不足以讓這個架構發揮吧。

2 則留言:

vvworm 提到...

或許ROR與Grails對Active Record的應用已經開創了新局,巧妙融合物件與DB

EC 提到...

很感謝您的高見。雖然讓我對自己的作文能力有些沮喪。

這篇文章要表達的重點之一,是在於各項技術有其適用範圍以及擅長領域。再好的技術也要去釐清怎麼用以及何時用。

我個人也非常欣賞ROR,這是個十分優美的技術;卻不認為它是個會拯救資訊界的通解。

釐清幾個基本的問題。當年發展出DB Centric的設計(以及發展出RDB)是要解決什麼? ROR的設計是為了解決什麼?有沒有一併解決掉前者要解決的問題?前者當年要解決的問題,由今天的角度來看,問題還存在嗎?

我猜,ROR/Groovy會有自己的一片天,但是無法替代傳統的DB Centric架構。