用MDA和傳統方法開發一個三層架構應用的對比

xuepiaofei發表於2006-03-27

轉自部落格中國   MIDDLEWARE 著,陳龍譯


1 執行摘要
最近,物件管理組織(Object Management Group, OMG)釋出了一種新的伺服器端軟體開發的思維模式,即模型驅動架構(MDA)。MDA 不同於以往傳統開發方法之處在於使用MDA 你首先要用UML 構建物件模型,然後通過程式碼生成工具和模式庫(pattern repository)從物件模型生成程式碼。OMG 認為MDA 有許多優點,其中最令人興奮的
就是開發人員生產率的提高。

這一案例研究的目的就是驗證或反駁關於基於MDA 的開發工具可以提高軟體開發生產效率的宣告。兩個團隊開發同樣的J2EE PetStore 應用,一個團隊使用了基於MDA 的開發工具,而另一個團隊使用傳統的企業級整合開發環境(IDE)以程式碼為中心(code-centric)的開發方式開發。

研究的結果是,MDA 團隊的開發速度比傳統的團隊快35%。MDA 團隊在330 小時內就完成了開發任務,而相比之下傳統的IDE 團隊用了507.5 小時。作為這一案例研究的結論,The Middleware 公司推薦那些致力於提高開發效率的專案組可以在他們的專案中嘗試使用基於MDA 的開發工具。

2 介紹
通過這一案例研究,你將瞭解到MDA 開發方式的概況,並且能夠看到一個接受這種開發方式的團隊獲得了什麼樣的生產率。如果你正在尋求如何使專案中的開發人員的生產率最大化,這份案例研究是你必讀的。

2.1 什麼是模型驅動架構(MDA)?
模型驅動架構是一種旨在使業務邏輯和應用邏輯與技術進展相分離的軟體開發思維模式。MDA 可以幫助你快速構建出與中介軟體無關的,具有優良架構,堅固的,可維護的程式碼。
MDA 開發方式的關鍵點在於以下這幾步開發過程:
1. 確定應用程式的業務需求。
2. 畫出業務模型的UML 圖,這些圖與任何具體實現它的開發技術(J2EE,.Net,CORBA 等)都無關。這個UML模型代表了核心的業務服務和元件,例如可以有定價引擎,購物車,訂單處理等模組。因為它完全和技術無關,所以這個UML 模型叫做平臺無關模型(Platform-Independent Model, PIM)。也就是說,不管你使用J2EE 還是.Net,這個UML 模型都是一樣的。你可以用一個MDA 專用建模工具來建造這種UML 模型。
3. 畫出應用程式的UML 圖,這些圖指定與某種技術(比如說J2EE)相關。這個UML 模型包含特定技術的元素,比如說特殊的J2EE 設計模式。這個UML 模型叫做平臺相關模型(Platform-Specific Model, PSM)。你可以手工建模,也可以用一個MDA 工具生成它的大部分,然後手工除錯需要特製的部分。
4. 最後,用一個MDA 工具生成應用程式程式碼。也就是說,不是基於UML 模型手工編寫程式,而是從UML圖生成程式的大部分。如果是J2EE,MDA 工具可以生成絕大部分servlet, JSP 和EJB。你剩下的工作就是填補上UML 無法建模的細節,比如業務邏輯。

2.2 誰支援MDA?
物件管理組織(OMG)創造了模型驅動架構。OMG 是一個業界標準組織,有幾百個組織成員,包括IT 使用者和開發商。OMG 是幾種被廣泛使用的標準的管家,包括統一建模語言(UML)和通用物件請求代理架構(CORBA)。因為用OMG 的開放過程制定,所以MDA 是一種中立於開發商的方法,任何廠商都可以建立一個用於輔助MDA 開發過程的MDA 工具。關於MDA 的更多資訊請參考OMG 關於這一主題的白皮書,位於http://javacentral.compuware.com/pasta下載)測試了雙方的程式碼的非迴圈依賴性(acyclic dependencies)。兩個團隊在非迴圈依賴性測試中都得了90%的高分。

最後,因為我們知道很多程式碼生成工具能夠產生"壞程式碼",所以我們檢查了雙方生成的程式碼。根據我們的檢查,我們相信生成的程式碼質量很好。

3.5 團隊概況
我們竭盡全力確保兩個團隊具有大體相近的技術集(skill-set),不會讓一個團隊比另一個具有無法比擬的優勢。每一個團隊成員都具有在多種應用伺服器上進行J2EE開發的豐富經驗。此外,為了平衡技術集之間的差異,我們花了很多時間把開發人員按照他們願意使用的工具和技術做了調整。兩個團隊還解決了一些小的編隊問題。這些時間不會被計算在最終的生產率資料中。

每個團隊包含3名成員:
一名高階J2EE架構師。這個人掌握自己開發環境的技術細節。他的職責是開發,做架構,合理地分配任務,最終實現規範。
兩名經驗豐富的J2EE程式設計師。這些人都具備至少3年的J2EE應用程式開發經驗。

3.6 專案計劃和管理概況
為了準確地記錄每個團隊工作日誌,我們分別和每個團隊每週召開例行電話會議。在電話裡我們對兩個團隊每週的經歷作了詳盡的記錄。兩個團隊都必須回答下列問題:
*你的團隊這周作了什麼?
*從效率的觀點看,這周好的方面有哪些?
*從效率的觀點看,這周哪些方面存在問題?

這些記錄的摘要會在這份案例研究的下一節作介紹。
在專案開始之前我們舉行了一個專案開工儀式,儀式上每個團隊都估算了他們多長時間能夠完成專案。另外,每個團隊每週都要提交上週的詳細時間表。時間表包括估算時間和實際使用時間的對比。

4 研究結果
在這一部分我們將論述案例研究的結果。結果被分為如下幾個部分:
在架構分析部分你將瞭解每個團隊使用的架構和J2EE模式。我們在文件後面建立了一個專用設計模式術語表來簡要地解釋每種模式。對於有抱負的J2EE架構師來說這個術語表將是一份有趣的閱讀材料。如果你不熟悉J2EE模式的話,你最好在閱讀架構分析部分之前先閱讀這個術語表。

在定性分析部分你將瞭解到每個團隊對他們選擇的開發方法的感性的思考。你將瞭解每個團隊遇到的問題和他們是怎樣克服問題的。在定量分析部分你將會看到每個團隊最終的生產率數字。

4.1 架構分析
4.1.1 UML和程式碼生成
兩個團隊都建立了物件模型的UML圖。而其實兩個團隊建立的的物件模型非常相似。每個團隊都作了如下抽象:
*使用者賬號
*使用者資料資訊
*產品
*產品目錄
*供應商
*購物車
*訂單
*排列項

傳統團隊用了一種開源工具為他們的物件模型建立UML圖。他們確實是為了設計和溝通的目的畫的UML圖,而不是為了從UML自動生成J2EE程式碼。不過,他們確實用了他們IDE的嚮導功能生成了JavaBean的accessor/mutator方法(也就是geter/seter方法),EJB元件,struts程式碼,異常處理程式碼和加速實現介面的樁程式碼(stub-code)。

MDA團隊用他們的MDA工具不僅建立了平臺無關模型還建立了平臺相關模型。他們用MDA工具的UML程式碼生成功能自動生成了比傳統開發團隊多的程式碼。生成的程式碼有JSP,EJB元件,Struts程式碼,異常處理程式碼和介面,還有許多設計模式和構建應用程式時用到的框架程式碼。不僅僅是框架程式碼,MDA工具還在程式碼生成模式(code-generation patterns)的基礎上利用UML物件模型生成了一個可以執行的應用程式。

4.1.2 Web層
兩個團隊在Web層都使用了servlet,Java Server Page,和JSP標記庫(taglibs)的組合。兩個團隊都用了Apache Jakarta Struts作為他們Web層開發框架。Struts是一個流行的建造基於J2EE的Web應用的開源框架。它鼓勵使用廣為接受的Model-View-Controller(MVC)設計模式。兩個團隊都調整了生成的程式碼使其更符合MVC思維模式。

4.1.3 EJB層
從架構性的觀點來看,兩個團隊的EJB層程式碼的具體不同之處在於他們選擇的模式。
模式                                                                           傳統團隊              MDA團隊
Session-entity wrapper                                              Yes                        Yes
Primary Key generation in EJB component            Yes                        Yes
Business delegate                                                      Yes                        Yes
Data Transfer Objects(DTOs)                                   Yes                        Yes
Custom DTOs                                                              Yes                        Yes
DTO Factory                                                                  Yes                         No
Service Locator                                                            Yes                         No
JDBC for Reading via Data Access Objects(DAOs)  Yes                         No
Business interface                                                     Yes                        No
Model driven architecture                                          No                        Yes

從上表可以看出,兩個團隊都用了很多J2EE設計模式。雖然這樣做在開發PetStore這樣的應用時顯得大材小用,但是我們還是想使用在實際專案開發中用到的模式,這樣就更能夠測試出MDA生產率的真實水平。

另外還請注意,傳統開發團隊使用了比MDA團隊更多的模式。當我們一開始做好這個比較表時就注意到了這一點。傳統開發團隊使用了額外的模式是否會使這次案例研究失效呢?畢竟,傳統的團隊使用更多的設計模式會讓人認為他們的開發過程會自然地被拉長。

為了回答這個問題,我們仔細分析了被使用的每個模式。我們也會見了兩個團隊的成員。完成這次研究後,我們關於這一問題的一致意見是雖然傳統團隊使用了更多的模式,但是比較結果還是非常正確的。為了幫你理解為什麼是這樣,讓我們看看每個傳統團隊使用了而MDA團隊沒有使用的模式吧:
The service locator 模式沒有給傳統團隊新增額外工作。實際上這個模式還節省了他們的時間,因為它簡化了EJB層的客戶端程式碼編寫,也包括EJB元件呼叫其它EJB元件的情況。由於是使用一個類中的靜態方法實現的,所以它減少了必要的程式碼行數。所有對EJB的訪問都是由這些方法完成的。

The JDBC for Reading via DAOs 確實需要傳統團隊花時間去實現;然而,如果假使他們不用這個模式的話,他們就不得不寫實體Bean來替代這些資料訪問物件(DAO)了。還有,MDA團隊需要手工編寫程式碼來排序資料,而這些工作傳統團隊可以通過JDBC for Reading模式完成。所以說,這種模式實質上沒有給傳統團隊增加任何工作量。

The business interface pattern 沒有給傳統團隊帶來任何工作量。據他們講,每個介面大概需要10分鐘。因為要使用MDA推薦的平臺無關模型建立業務物件模型,所以MDA團隊也要建立業務介面,只不過層次更高而已。

The DTO Factory pattern花了傳統團隊一點實現和測試的時間。但是由於這種模式減少了應用程式中的程式碼量,所以實際上還是節省了他們的時間。

同樣值得注意的是傳統團隊擁有世界頂級的J2EE模式專家(Owen Taylor,我們J2EE模式教程的作者)。這種專業的模式知識不是普通的IT開發組織所能擁有的。所以傳統的團隊使用模式比MDA團隊多就可以理解了。正是因為傳統的開發團隊選擇的模式沒有拖延他們開發的時間,所以我們得出的結論是沒有明顯的跡象表明這次生產率比較是無效的。

4.1.4 安全
兩個團隊開發的應用程式大部分都是相近的。不過兩個團隊在安全方面卻產生了差異。
傳統團隊使用了一個身份驗證過濾器(authentication filter)來解決安全問題。這個過濾器察看當前請求的頁面是否是受限制的,如果是的話就要看使用者是否已經登入了(登入資訊儲存在HTTP會話裡)。這個過濾器完全是這個團隊自己寫的。過濾器實現javax.servlet.Filter介面。

相比之下,MDA團隊使用了MDA工具輔助開發安全系統。他們的MDA工具提供了一個安全框架可以使他們從不同的身份驗證方法中選擇,這些方法其中包括簡單驗證,基於摘要的,基於表單的,和程式設計實現的驗證。該組選擇了程式設計的方法。這一框架還提供了登入和退出的JSP頁面,該組定製了這些頁面把他們用在了PetStore中。

4.2 定性分析結果
在這部分,我們將評論兩個團隊感性的思考,這些是從他們每週提交的資料中總結出的。
4.2.1 傳統團隊
4.2.1.1 傳統團隊第一週
傳統團隊採用迭代式的原型法開發。在第一週裡,他們搭建了一個簡單的原型,這樣就可以架構他們專案的設計模式基礎。對於他們來說建立一個得心應手的開發環境是一件相當棘手的問題。在讓StarTeam版本控制和他們的IDE有效結合的過程中就遇到了一些問題。在第二週他們才下決心用替代方法繞過這一問題。第一週他們還花了很多時間在架構物件模型上,比如確定包結構等和開發環境有關的問題。

從生產率的觀點來看,第一週他們印象最深的就是IDE的能力。他們發現IDE和被選擇的應用伺服器整合得很好,而且也具有很好的程式碼生成能力。這都得益於每個團隊成員都有以前使用這種IDE的經驗。

這周他們生產率存在的問題和檔案共享,溝通交流,執行程式碼複查,維護包結構的穩定性有關。

4.2.1.2 傳統團隊第二週
第二週,傳統團隊開始分配不同的開發角色。一名隊員負責model(EJB)層,另一個隊員負責View(web)層,第三個隊員提供兩個層之間的輔助類和介面。該隊決定以用例的方式構建他們的系統,一次只關注一個用例。這一週他們在開發使用者賬戶維護用例,例如
登入,退出,使用者建立和使用者偏好維護。

從生產率的觀點來看,這周他們發現Struts框架發揮了作用。他們發現編寫Struts程式碼的效率很高。另外他們還決定使用一種讓web層和業務層解耦的策略。這種策略讓實現"樁"的程式碼能夠植入沒有完全建好的程式碼中。他們通過屬性檔案和附錄中的業務代理(business delegate)設計模式在"樁"和"真實"程式碼之間切換他們這周的生產率問題都是一些開發團隊在開始會遇到的典型問題,例如堅持使用原始碼控制。在IDE的使用上也遇到了困難。情況是,如果他們試圖從IDE生成J2EE元件然後修改的話,這些修改過的元件就很難再逆向到IDE中

4.2.1.3 傳統團隊第三週
這周,傳統團隊繼續開發他們的產品目錄瀏覽和購物車等功能。
從生產率的觀點來看,這周他們解決了如何使用版本控制協作開發的問題。他們還構建了隊員用到的介面庫,這樣就減少了構建時(build-time)的依賴性。在開發的這一階段,每個隊員的效率都非常高,而且由於專案模組分解的非常合理,每個隊員都有自己的工作領域。還有的就是他們的IDE在程式碼生成上也起了很大的作用。

他們這周的生產率的唯一問題就是對PetStore規範描述的需求的理解和執行了一些對購物車部分的重構。

4.2.1.4 傳統團隊第四周和第五週
在最後兩週裡,傳統團隊在對最後一個用例編碼,測試和除錯後完成了他們的應用程式。他們還合併了隊員的程式碼,去掉了實現樁的程式碼。這周獲得高效率的因素有這麼幾點。他們始終得益於選擇的樁實現架構。只要他們把介面確定下來就基本不需要什麼溝通了,所以編碼的效率非常高。同時,因為他們的IDE在WSDL自動生成和SOAP服務部署方面的能力,他們的web服務實現構建得也非常快。

這周遇到的問題包括對程式碼的重構和重新分析,例如在資料訪問層就存在一些缺陷。由於他們的應用分成好多層也導致了一些問題,因為當出現錯誤時除非仔細檢視這些層否則就不清楚問題出在哪一層。他們還有其他一些無足輕重的問題和Struts和屬性檔案有關。

4.2.2 MDA團隊
4.2.2.1 MDA團隊第一週
第一週,MDA團隊作的都是一些一般專案團隊在專案開始時做的典型步驟。他們用MDA工具的UML建模能力建立了一個詳細的物件模型。配製好了他們的原始碼控制系統,然後就把專案任務分配給每個隊員。他們還設定了一個專案目錄結構並作了一些初始的開發工作。

從生產率的觀點來看,好的方面就是他們發現不需要建造過多的元件,因為MDA工具具備生成這些程式碼的能力。實際上他們還發現工具不僅能夠生成這些元件,還能生成框架程式碼把這些元件連線起來產生一個有機的應用程式。該團隊估計應用程式的50%到90%都可以自動生成,包括web頁面,Struts action,EJB實體bean,EJB會話bean,J2EE設計模式的框架程式碼和資料庫表。

這周的關鍵問題是掌握MDA方法的核心思想。這種方法和他們以前用的傳統方法不一樣,他們需要抓緊時間來熟悉工具提供的許多層和結構。

4.2.2.2 MDA團隊第二週
第二週,MDA團隊開始投入到開發工作中。他們完成了網站的很多部分,包括UML物件模型,元件框架,站點導航系統,JSP模版(用Dreamweaver開發),主頁,EJB購物車的大部分功能和使用者賬戶管理的一小部分。

從生產率的觀點來看,好的方面是他們能夠從UML物件模型生成EJB會話/實體bean程式碼,web層程式碼,和一個DDL模型。建立測試資料集也同樣非常簡單。最後,由MDA工具生成的整體應用程式框架可以使他們快速地把元件組裝起來。

這周遇到的困難和傳統團隊遇到的差不多。他們有一些開發環境上的困難,包括在一個協作的開發環境中習慣使用原始碼控制系統。他們花了一點點時間就把工具配製好了。他們也知道著手使用MDA工具需要時間來學習,所以在這周裡他們都在不停地學習以適應從傳統的開發方法轉變到MDA的思維模式上來。最後,他們意識到MDA的程式碼生成能力有點過於強大了,生成了一些他們不需要的程式碼。他們確實注意到有必要修改工具用於生成程式碼
的演算法。在一個實際的專案中這樣做可能會減少麻煩,但是這超出了這次案例研究的範圍。

4.2.2.3 MDA團隊第三週
第三週,MDA團隊完成的系統用例比上週多了幾個,包括購物車,訂單處理,賬戶管理,登入模組。從效率的角度來看,這周有幾件好事。由於MDA工具輔助生成了程式碼,他們非常容易就構建好了安全系統。他們使用JSP模版的想法也起了作用。把JSP的通用程式碼集中在JSP模版中,這些通用的程式碼就可以集中在一個地方更新了。

這周有一個開發人員開始體會MDA方法的好處,並且情不自禁地做出瞭如下結論:
MDA 的價值和OO 的價值相似,只要在設計階段多下功夫,在實現階段就能得到回報了。一旦你做了一兩個應用程式之後,你就會真正開始從它受益。不過這周他們也遇到了一些困難。在Struts上遇到的一些細節問題一度造成他們工作停頓。他們還有一些會話
識別符號和瀏覽器的cookies的問題。這周最後遇到的問題是關於MDA的。他們發現由於在認為應該生成的程式碼和實際生成的程式碼之間存在差距,有時會感到開發工作非常鬱悶。有時他們的開發工具要麼產生他們並不需要的程式碼要麼產生過剩的程式碼,這些都無助於提高效率。他們認為這些問題都是由於他們在MDA和程式碼生成上的經驗不足造成的,因為他們在預測將會產生出什麼程式碼時毫無經驗。他們相信隨著使用MDA工具的經驗的增加這些問題將迎刃而解,而且是用得越多,效率就越高。正是由於對MDA工具一時的不熟悉,導致他們的時間有點拖延。

4.2.2.4 MDA團隊第四周
第四周,MDA團隊完成了他們的開發、測試和除錯任務。
從提高效率的角度來看,MDA程式碼生成,以及由MDA提供的Struts框架,身份驗證框架都是值得肯定的。同時,模組整合過程也進展順利。

這周遇到的問題是有時生成的程式碼變成了一種負擔。他們要麼徹底修改,要麼丟棄不用。不過他們也認識到MDA工具生成的程式碼是基於模式的,這就給他們手寫程式碼助了一臂之力。他們也有一些MDA工具的原始碼合併問題。他們吸取的教訓是當你使用一種象MDA工具一樣的產品時,你必須隨時掌握工作的進展,並且要注意如何使用好版本控制把他們編制到一起。

4.3 定量統計結果
每個團隊最終使用的開發小時數統計結果:
團隊                    初始估算小時數            實際的小時數
傳統團隊                  499                               507.5
MDA團隊                 442                                330
就像你看到的,在這次案例研究中MDA團隊取得了絕對性的勝利。他們在預算的時間之內完成了任務。需要強調的是MD團隊不是立刻就利用了這種效率上的優勢,而是隨著專案的展開效率的優勢才逐漸顯現出來。隊員把這歸咎於MDA工具,因為它對於絕大多數開發人員來說都是一種新的產品,所以需要一個適應的過程。實際上有一個隊員認為作為他們用這種工具開發的第一個專案,如果不存在這個學習的過程的話他們應該比實際的情況還
要再快10-20%。

另一點也需要強調,在這個專案裡我們沒有執行"bug跟蹤";不過我們作了前文提到的手動用例測試。有意思的一點是在對傳統團隊的測試過程中發現了一些bug,但是MDA團隊卻沒有。我們相信這是由於使用MDA開發方式產生的程式碼的堅固性造成的。

5 結論
根據這次案例研究的結果,The Middleware公司被MDA團隊使用模型驅動架構所獲得的效率所折服。我們鼓勵那些致力於提高開發效率,特別是那些涉及企業級應用和Web服務的組織,在專案中嘗試使用基於MDA的軟體開發工具。當然有必要給開發團隊短期的MDA方法和開發工具入門時間,由於在開發的過程中,特別是以後的應用中才能收到效率的回報,所以付出的努力完全值得。

我們認為MDA還有其他的一些價值。比如,平臺無關模型(PIM)具有相當長的預期使用期限。軟體開發組織有必要建立一個這樣比技術生命週期還長的業務物件模型。和使用不同的工具和技術的開發人員交流時,這將是一個非常重要的工具。

我們覺得MDA的另外一個優點就是可以讓一個組織中具有淵博知識的架構師確保平均水平的開發人員能夠協調一致地使用設計模式。用MDA工具自動生成實現模式的程式碼,然後按照架構師的意圖作調整,架構師就可以做到這一點。這樣,使用模式就很自然地變成了開發人員編碼工作的一部分。

我們有一個隊員是這樣評價MDA的:"它讓一名腦外科醫生成為一名更好的腦外科醫生,但是不會讓一個看大門的人成為腦外科專家。"他的意思是MDA讓一個有經驗的架構師的能力得以充分發揮,能夠更好地把握專案的方向。同時你還要你的職員瞭解J2EE模式和最佳實踐,物件導向的開發,和一些架構方面的考慮。

最後,在程式碼和應用程式質量方面,一個很突出的觀測結果就是在手工編寫程式碼時發現的bug需要修改和複測,而修改和複測還將不斷影響整體開發質量。MDA團隊通過模版自動生成程式碼就不會有這些額外的步驟了。

有必要指出,這次案例研究中很多MDA的特性沒有被評估到,比如應用程式的效能和可維護性。我們確實也作了一些必要的效能測試,用來考查兩個應用的效能是否相近。但是為了得到全面客觀的結果,我們覺得可以把這些測試放到今後的研究中。同樣,我們想在可維護性方面進行比較也將是非常有意思的,你將看到相比一個用傳統方法開發出的系統,改變MDA建造的系統的程式碼將是多麼容易的事。畢竟,當你重構一個基於MDA的系統
只需修改原來的UML模型然後再重新生成程式碼即可。

相關文章