物件導向軟體工程方法學實踐 (轉)

worldblog發表於2007-12-04
物件導向軟體工程方法學實踐 (轉)[@more@]
面向工程方法學實踐

作者:北京工業大學學院 趙曉華

文章來源:AKA雜誌

  兩位研究物件導向軟體工程的美國學者 (Stave Halladay和Michael Wiebel) 曾這樣說:“一般的面
向物件()思路不過是一批烏合之眾,把靈機一動、隨機應變的技巧用於他們絞盡腦汁抽象出來的
‘物件’而已。即使是最優秀的 OOP 員,他們所能對付的極限也莫過於中等規模的開發專案。倘若
程式設計師不足,規模又很大,那麼採用 OOP 只能把你引入漫無邊際的泥沼之中。” 

  一方面是幾乎沒有一位軟體工程學者認為 OOP 是完美無缺的,另一方面是 OOP 勢如破竹,近乎每一
種最新推出的程式開發工具或語言都採用了 OOP 思路;一方面是越來越多的“烏合之眾”在毫無章法、
隨心所欲地處理著“物件”,另一方面是經過近 30 年的積累已經擁有了最大多數的結構化軟體方法
的日漸萎縮……面對這一現實,研究軟體工程方法學的專家們紛紛指出:“當前擺在方法學面前
的一個重要課題是:從理論上理解 OOP 具有強大生命力的天然合理性,並完善物件導向軟體工程方法學
體系。” 

  一年來我們透過國內外一些實用系統的開發實踐,對物件導向的軟體工程方法進行了較為深入的學習
和探討,特別是在北京市公路局計算機系統的一期工程實踐中,借鑑國外軟體設計經驗,較系統地採用了
物件導向軟體工程方法,受益匪淺。 

一、 是“設計主導”還是“程式主導” 
  在一個系統開發過程中是隻採用 OOP 還是採用了OOSE(物件導向軟體工程)方法,關鍵看整個開發
過程是“設計主導”還是“程式主導”。 

  近年來,大量先程式序開發工具進入我國,這對提高軟體開發無疑具有很大的作用。然而,它們
又往往使程式主導型軟體開發人員在“以程式代系統”、“以演算法代設計”的誤區裡越陷越深。 

  一般的軟體開發人員(包括那些只見程式不見系統的程式設計師)主觀上都認為:軟體開發不應“系統設計
主導”而應“程式演算法主導”。但是用下面幾個問題考察一下,結果往往相反。 

問題1 在進行軟體設計和選擇軟體開發工具之前,是否進行開發方法學的選擇? 

  所謂方法學是指組織軟體生產過程的一系列方法、技術和規範。方法學是軟體開發者長年失敗和成功
經驗的理論性總結,從軟體重用的思路來說,方法學重用的價值遠非某些程式重用可比。 

  以北京市公路局系統為例。首先,在系統調查階段我們瞭解到:這個系統要分期 (遞增式) 開發。由
於處於機構改革時期,系統生存期內的使用者需求和系統結構變因很多。這表明目標系統應該具有較強的可
維護性,即每期開發成果應在後續工程中具有較高的可重用率。其次,一期工程的工作量相當大(最後成
果包括 124 個模組、72 類報表、119個表、439 個視窗、912 個資料視窗),而開發者對公路局業
務不瞭解,多為經驗不足的大學生,理解需求的能力較低。這表明採用的開發方法學必須能最大限度地減
少重複勞動,實現開發過程中的成果共享和重用;必須能支援消除需求理解誤差的調整工序,使下游成品
階段的設計變更比較容易進行。 

  在開發此係統之前,我們承接了一個國外軟體的下游開發任務。由於它採用了物件導向的軟體設計,
使我們深刻認識到國內外軟體開發方法學和技術上的差距,頗受啟發。 

  參照我們承接的國外軟體開發工作量計算方法,即僅下游120個模組 (含報表) 的編碼和測試為41人
月,那麼公路局系統從上游設計開始近200個模組和報表、100多個資料庫表的開發工作量至少也應在120
人月以上。由於採用了物件導向的軟體工程方法,儘管開發人員大多經驗不足,但是第一期工程總工時最
終仍控制在 80 人月以內,降低成本1/3左右。同時在系統可維護性、重用度及其他功能和指標上,
均超過了我們以往採用結構化方法開發的系統。 

  對停留在程式主導級開發的軟體開發人員來說,他們選擇 OOP 的原因也往往是被動的。其實,在程
序主導開發者的辭典中是找不到“方法學”這一詞的,或者把“方法學”與“程式演算法”混為一談。至於
把 OOP 看成是 OOSE 的全部就更不足為怪了。 

問題2 物件抽象的出發點是現實世界的問題描述,還是可的例項物件? 

  在現實世界早期抽象階段,物件導向方法與其他方法區別並不大,都要從現實世界的問題描述出發,
即從使用者介面、問題領域的知識和經驗出發,構築現實世界的問題模型,也就是確定目標系統是“做什麼
的”。物件導向的問題分析模型從3個側面進行描述,即物件模型 (物件的靜態結構)、動態模型(物件相
互作用的順序)和功能模型(資料變換及功能依存關係)。軟體工程的抽象原則、層次原則和分割原則同樣
適用於物件導向方法,即物件抽象與功能抽象原則是一樣的,也是從高階到低階、從邏輯到物理,逐級細
分。每一級抽象都重複物件建模 (物件識別)→動態建模(事件識別)→功能建模(操作識別)的過程,直到
每一個物件例項在物理(程式編碼)上全部實現。 

  物件抽象是從邏輯級還是物理級出發,與開發前是否進行方法學選擇一樣,也是區分OOSE 與 OOP 的
試金石。由於許多工具或語言(如PB、C++、Motif) 都支援OOP,使一些程式級系統開發人員可以很方便
地不經過邏輯抽象就直接開發物理物件,在早期階段意識不到從物理層即例項物件出發進行系統開發的禍
患,孰不知正是這種隨心所欲的 OOP 不僅無法發揮物件導向方法應有的優越性,而且還會給開發後期帶
來大量返工作業。 

  和以往採用結構化方法一樣,我們在系統設計階段也引入了原型化方法,以便用系統樣品即原型與用
戶對話,求得對需求理解的勾通,避免或減少後期返工。大多OOP工具都為開發原型提供便利,問題在於
原型與最終產品間的關係,即原型是邏輯物件還是物理物件的樣品。若是後者,那就等同於最終產品。在
木已成舟時再讓使用者評審,若發現問題,要麼推倒重來,要麼強迫使用者削足適履。事實上,我們為設計評
審而基於邏輯物件開發的原型,相當部分被使用者否決。但由於尚未進行物件例項即物理級開發,而是使用
超類物件原型統一模擬物件事件和操作,所以無論是物件模型、動態模型還是功能模型,修改起來都不困
難。 

問題3 設計階段是否先設計超類,是否在例項物件設計開始之前完成超類物件的實現? 

  物件導向方法開發出的軟體具有較強的可重用性,這種重用包括開發專案內部的重用和外部的重用。
重用依存於超類設計,沒有超類的物件系統好比“把洗衣機當米缸”,不能物盡其用。超類設計的好與不
好,首先看其內部重用率的高低,內部重用率高,必然外部重用率也高。 

  由於系統開發工期緊、工作量大,而我們的開發隊伍年輕,經驗和人力都不足,內部重用率高的超類
開發無疑是我們的救星。它可以減少重複勞動,易於統一規格,對複雜問題統一攻關、統一解決,便於統一
維護。 

  對超類的抽象即例項物件的泛化原則,我們是從下面幾個方面考慮的: 

  (1)尋找大多數例項物件的共同行為。

    例如“列印報表”、“查詢靜態程式碼表”、“錄入資料庫表資料”等。 

  (2)超類的多型性設計要保證使用超類繼承關係可以滿足各子類的操作要求。

    例如,繼承同一個“資料錄入”祖先視窗,可以完成不同結構資料庫表的資料錄入。 

  (3)利於資訊的隱蔽性,不會破壞資料的完整性,利於將複雜問題簡單化。

    例如,對具有複雜關係、結構及相關存取操作的資料庫表集的維護。如果不使用一個泛化類將數
據結構及其相關操作封裝起來,下層程式設計師要想操作有關庫表就必須對庫表設計有深入的瞭解,並且確保
程式演算法設計不得破壞資料的相關一致性,這將大大增加和測試的難度,要求程式設計師有較豐富的
經驗。而採用這種泛化類 (公用、公用過程) 後,程式設計師所要做的只是發“訊息”和取“輸出信
息”了。 

  (4)有利於推行開發規範,統一介面風格。

    我們在開發國外軟體中受到的最大磨練是:國外對使用者介面 (報表、螢幕) 一絲不荀的嚴格要
求。所有螢幕按鈕的高、寬、起始位置都用精確到小數點後 3 位的 X、Y 座標進行規定。這樣出來的產
品使人看上去就有賞心悅目之感。但是如果人人都做介面視窗、按鈕的精細調整,工作量勢必成倍增長。
採用螢幕介面模版超類的繼承關係,結合特化處理,問題便可迎刃而解。 

  顯然,超類的設計和實現必須在程式設計師普遍進行例項物件開發之前完成。也就是說,OOSE 的上游系
統設計人員必須文武 (設計與程式設計) 雙全,能夠擔負起超類物件的程式實現與測試任務,這與結構化方法
的上層系統設計人員基本可以不程式設計有所不同。同時,超類物件在下游開發過程中必須經常吸收特化過程
中的反饋(包括來自使用者的反饋),進行相應的調整修改。所以OOSE擔任超類物件設計與實現的設計人員很
難像結構化方法那樣進入程式設計階段後就可以稍事輕鬆,他們往往始終離不開程式設計現場。 

  如果設計階段不預先設計和開發出超類物件,在同一專案的多數開發者之間沒有可以共同繼承的祖先
物件,甚至在各個開發人員自己的作用範圍內都不使用繼承關係,那麼這不僅不是OOSE,就連稱之為OOP
都很勉強。 

問題4 如何處理物件模型物件導向關聯式資料庫的對映? 

  物件導向的資料庫設計方法可以用於各種資料庫,如層次型、型、關係型,當然也包括物件導向
型。OOSE 中的資料庫設計無疑必須採用物件導向的資料庫設計方法。 

  資料庫設計也稱資料庫模式,基本上由3個層次的模式構成:從特定應用角度來看待DB設計的外部
模式;從組織或企業角度出發進行的DB設計即概念模式;處理對應特定 DBMS 特徵與侷限性的DB設計即內
部模式。具體而言,內部模式是資料庫的定義,邏輯模式是表集合的邏輯定義,外部模式是從特定應
用角度看的區域性DB。外部模式與邏輯模式之間的介面是檢視、儲存過程或其他駐在端的DB處理程
序。 

  如果在抽象出的物件模型中,各個應用分別是一個或多個超類物件的子物件,那麼,選擇適當細分層
次的物件模型將其對映到概念模型,是資料庫庫表物件設計的關鍵。外部模式與概念模式之間的介面越
少、越簡單越好,這樣的程式設計簡單,資料庫和程式都易於維護。也就是說,區域性化是個重要的設計原
則。 

  OOP多是資料庫的後端處理,是基於既存資料庫的。因此無論是否進行過問題世界的物件建模,以及
是否將物件模型合理地對映到資料庫邏輯模式 (物件導向資料庫設計),OOP 都可以工作。 

問題5 程式設計時是否先調查有無可重用 (繼承) 物件,是否參與下層物件對上層物件、超類物件的反饋? 

  埋頭於自己分擔的程式對結構化方法或許是必須的,但在物件導向方法中擔任程式設計的開發人員,
應該先去調查物件資料辭典中有無其他開發人員已經完成、自己稍加特化就可重用的物件。從總體上說,
物件的共享、重用應該由上層設計人員統一管理,以便保證物件風格的一致性,避免衝突。但是,物件的
獨立性、封裝性和多型性都很便於重用,這是結構化系統所不能比擬的,而重用是軟體開發方法學的最重
要思想之一。上層設計人員往往不可能面面俱到,懂得軟體設計理論的開發人員,即使只開發下層程式也
應採用最省力、最有效率的程式設計方法,即大量使用重用物件。 

  在繼承超類物件和重用他人物件時,若發現有設計不合理的地方,應該及時反映給物件開發的承擔
者。 

  對上層設計人員來說,一方面應該鼓勵程式實現人員重用既存物件,另一方面應透過開發人員共享對
象資料辭典,使個別的物件重用能夠立即反映到整體物件模型中,以保證設計變更時的一致性。 

二、物件導向方法與結構化方法比較 
  分析是問題抽象 (做什麼),設計是問題求解 (怎麼做),實現是問題的解 (結果)。任何方法學對客
觀世界的抽象和求解過程都是如此。在問題抽象階段,結構化方法程式導向,按照資料變換的過程尋找問
題的結點,對問題進行分解。因此,與物件導向方法強調的物件模型不同,描述資料變換的功能模型是結
構化方法的重點。如果問題世界的功能比資料更復雜或者更重要,那麼結構化方法仍然應是首選的方法
學。如果資料結構複雜且變換並不多,那麼如以過程主導分析和設計,一旦有系統變更就會給下游開發帶
來極大混亂。 

  由於對過程的理解不同,程式導向的功能細分所分割出的功能模組有時會因人而異。而物件導向的對
象細分,從同一問題領域的物件出發,不同人得出相同結論的比率較高。 

  在設計上,結構化方法學產生自頂向下、結構清晰的系統結構。每個模組有可能保持較強的獨立性,
但它往往與資料庫結構相獨立,功能模組與資料庫邏輯模式間沒有對映關係,程式與資料結構很難封裝在
一起。如果資料結構複雜,模組獨立性很難保證。物件導向方法抽象的系統結構往往並不比結構化方法產
生的系統結構簡單,但它能對映到資料庫結構中,很容易實現程式與資料結構的封裝。 

  在軟體工程基本原則中有一條“形式化原則”,即對問題世界的抽象結論應該以形式化語言 (圖形語
言、偽碼語言等) 表述出來。結構化方法可以用資料流圖、系統結構圖、資料辭典、狀態轉移圖、實體關
系圖來進行系統邏輯模型的描述;而物件導向方法可以使用物件模型圖、資料辭典、動態模型圖、功能模
型圖。其中物件模型圖近似系統結構圖與實體關係圖的結合,動態模型圖類似狀態遷移圖,功能模型圖類
似資料流圖。 

  公路局系統有 100 多個資料庫表,但資料的加工 (變換) 很單純,如果當初選擇結構化方法學,情
況會怎麼樣? 

  在問題抽象的最初階段不會有太大差異。由於資料變換少,可以把物件和物件的操作看成一一對應,
即最初問題描述的物件模型與功能模型基本一致。以其中計劃管理處子系統為例,物件是計劃管理員、規
劃管理員、概預算管理員、統計管理員,功能 (操作) 是計劃、規劃、概預算、統計。 

  問題存在於下層抽象裡。 

  首先,許多公共超類物件設計與結構化方法相悖,因為它破壞了過程的連續性及系統結構的邏輯層次
性,把一些下層模組及在過程分析中沒有語義的物件,放在系統結構的上層。因此如果採用結構化方法,
須將繼承關係改為下層模組關係。但是事實上,祖先物件的一些狀態 (屬性值) 是從主控模組直接得
到指示而確定的;從控制角度說,它的確處於系統的上層地位。如果採用結構化方法,結果將是要麼把系
統結構變成網路狀,失去結構化特徵,要麼放棄這種統一完成重複性勞動的設計方案。 

  其次,應用物件模型向資料庫概念模式的對映設計也是該系統採用物件導向方法的一個標誌。如果使
用結構化方法,資料庫模式可能對映客觀世界的資料結構。由於公路、養路單位、管理單位、路況、橋
梁、隧道及道路上的綠化情況等各實體間客觀存在著複雜的多重關係,其結果可能定義出一個像蜘蛛網似
的關係庫結構,因而大大加重了資料庫前端應用程式設計和資料庫維護的負擔。 

  總之,該系統若使用結構化方法,系統結構和資料庫結構都可能成為網狀結構,且互相無關。而目前
採用的物件導向方法,系統結構和資料庫結構都是多重繼承結構,相互存在對映關係。顯然前者較後者復
雜性高、可維護性差、內部重用難度大、重用率低。 

  其實,無論是用什麼方法學開發軟體,交給使用者的都應該是滿足使用者當前需求的軟體。使用者在短期內
不會發現開發者使用先進方法學給他們帶來的益處,倒是開發者本身由於大大減輕了開發負擔而最先受
益。但是隨著時間的推移,獲得最大收益的還是使用者,因為軟體的長期質量(包括維護成本低和生存週期
長)給使用者帶來的好處才是根本的。 

三、方法學是思路不是定律 
  對於方法學,我們是這樣理解的: 

  (1)方法學的目的是:使後人分享前人的成功,避開前人的失敗,把注意力集中在尚未開拓領域的
創造性勞動上。所以方法學與開發人員的創造性是絕不衝突的。它既不能像法律那樣靠權威來界定是非邊
界,也不能像定律那樣透過證明和推理給出普遍結論。如果一定要做比喻的話,它好比人的世界觀。 

  (2)沒有放之四海而皆準的方法學,任何方法學都有其侷限性,所以軟體開發人員大可不必拘泥於
某種特定的方法學。 

  例如,物件導向方法的物件模型圖,這種形式化語言遠不如結構化方法的結構圖和資料流圖簡單明
了,倘若把公路局系統全部用物件模型圖表述出來,至少也要幾十頁。由於最上層功能模型與物件模型是
一致的,所以我們採用的是結構化方法的系統結構圖。 

  (3)事實表明,由 OOP 帶動的 OOSE 方法確實比結構化方法更能自然地抽象現實世界,而且一些 
OOP 工具確實已相當成熟。相反,結構化方法及開放平臺下的結構化程式開發工具,雖然不能說止步不
前,但其近年來的進步是有限的。 

  (4)根據我們的體會,對實踐 OOSE 有以下一些建議:

    1 最好在選定方法學後,對全體開發人員進行一次關於物件導向方法學的培訓。
    2 由於有超類物件的提前開發工作,OOSE 的上游設計工作量比結構化方法的上游工作負擔重,
時間和人力應該更充足一些。否則到下游開發後再追加或多次修改變更超類物件,容易造成混亂和無效勞
動。
    3 由於系統越大物件類越多,為了便於內部重用和共享,應該建立電子化的物件資料辭典,以便
對物件進行統一歸類管理。
    4 應該有嚴格的命名規則,如果可能,應將命名規則整合到資料辭典中。
    5 下層開發鋪開後,如果發現應該對某些例項物件泛化成新的超類物件,必須儘快進行新超類追
加的設計,變更越快越好。
    6 子物件繼承超類物件後,發現超類設計的缺陷是常有的事。開發隊伍內部應有很暢通的反饋渠
道,使超類得到及時的修正。子物件切不可輕易將超類物件封殺掉,使系統失去統一控制。遵從系統設計
中定義的繼承關係進行例項物件開發應該成為全體開發人員的理念。
    7 物件導向設計的好處越到後來越顯著,特別是在和擴充方面。



來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-988342/,如需轉載,請註明出處,否則將追究法律責任。

相關文章