[ZT] 物件導向軟體工程方法學實踐

來源:互聯網
上載者:User

兩位研究物件導向軟體工程的美國學者 (Stave Halladay和Michael Wiebel) 曾這樣說:“一般的物件導向編

程(OOP)思路不過是一批烏合之眾,把靈機一動、隨機應變的技巧用於他們絞盡腦汁抽象出來的‘對象’而已。

即使是最優秀的 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設計的外部模式;

從組織或企業角度出發進行的DB設計即概念模式;處理對應特定 DBMS 特徵與局限性的DB設計即內部模式。具

體而言,內部模式是資料庫的SQL定義,邏輯模式是表集合的邏輯定義,外部模式是從特定應用角度看的局部DB

。外部模式與邏輯模式之間的介面是視圖、預存程序或其他駐在伺服器端的DB處理常式。

  如果在抽象出的物件模型中,各個應用分別是一個或多個超類對象的子物件,那麼,選擇適當細分層次的

物件模型將其映射到概念性模型,是資料庫庫表對象設計的關鍵。外部模式與概念模式之間的介面越少、越簡單

越好,這樣的程式設計簡單,資料庫和程式都易於維護。也就是說,局部化是個重要的設計原則。

  OOP多是資料庫的後端處理,是基於既存資料庫的。因此無論是否進行過問題世界的對象建模,以及是否將

物件模型合理地映射到資料庫邏輯模式 (物件導向資料庫設計),OOP 都可以工作。

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

  埋頭於自己分擔的程式對結構化方法或許是必須的,但在物件導向方法中擔任程式設計的開發人員,應該

先去調查對象資料辭典中有無其他開發人員已經完成、自己稍加特化就可重用的對象。從總體上說,對象的共

享、重用應該由上層設計人員統一管理,以便保證對象風格的一致性,避免衝突。但是,對象的獨立性、封裝

性和多態性都很便於重用,這是結構化系統所不能比擬的,而重用是軟體開發方法學的最重要思想之一。上層

設計人員往往不可能面面俱到,懂得軟體設計理論的開發人員,即使只開發下層程式也應採用最省力、最有效

率的編程方法,即大量使用重用對象。

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

  對上層設計人員來說,一方面應該鼓勵程式實現人員重用既存對象,另一方面應通過開發人員共用對象數

據辭典,使個別的對象重用能夠立即反映到整體物件模型中,以保證設計變更時的一致性。

二、物件導向方法與結構化方法比較
  分析是問題抽象 (做什麼),設計是問題求解 (怎麼做),實現是問題的解 (結果)。任何方法學對客觀世界

的抽象和求解過程都是如此。在問題抽象階段,結構化方法面向過程,按照資料變換的過程尋找問題的結點,

對問題進行分解。因此,與物件導向方法強調的物件模型不同,描述資料變換的功能模型是結構化方法的重點

。如果問題世界的功能比資料更複雜或者更重要,那麼結構化方法仍然應是首選的方法學。如果資料結構複雜

且變換並不多,那麼如以過程主導分析和設計,一旦有系統變更就會給下遊開發帶來極大混亂。

  由於對過程的理解不同,面向過程的功能細分所分割出的功能模組有時會因人而異。而物件導向的對象細

分,從同一問題領域的對象出發,不同人得出相同結論的比率較高。

  在設計上,結構化方法學產生自頂向下、結構清晰的系統結構。每個模組有可能保持較強的獨立性,但它

往往與資料庫結構相獨立,功能模組與資料庫邏輯模式間沒有映射關係,程式與資料結構很難封裝在一起。如

果資料結構複雜,模組獨立性很難保證。物件導向方法抽象的系統結構往往並不比結構化方法產生的系統結構

簡單,但它能映射到資料庫結構中,很容易實現程式與資料結構的封裝。

  在軟體工程基本原則中有一條“形式化原則”,即對問題世界的抽象結論應該以形式化語言 (圖形語言、

偽碼語言等) 表述出來。結構化方法可以用資料流圖、系統結構圖、資料辭典、狀態轉移圖、實體關聯圖來進

行系統邏輯模型的描述;而物件導向方法可以使用物件模型圖表、資料辭典、動態模型圖、功能模型圖。其中對

象模型圖近似系統結構圖與實體關聯圖的結合,動態模型圖類似狀態遷移圖,功能模型圖類似資料流圖。

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

麼樣?

  在問題抽象的最初階段不會有太大差異。由於資料變換少,可以把對象和對象的操作看成一一對應,即最

初問題描述的物件模型與功能模型基本一致。以其中計劃管理處子系統為例,對象是計劃管理員、規劃管理員

、概預算管理員、統計管理員,功能 (操作) 是計劃、規劃、概預算、統計。

  問題存在於下層抽象裡。

  首先,許多公用超類對象設計與結構化方法相悖,因為它破壞了過程的連續性及系統結構的邏輯層次性,

把一些下層模組及在過程分析中沒有語義的對象,放在系統結構的上層。因此如果採用結構化方法,須將繼承

關係改為下層模組調用關係。但是事實上,祖先對象的一些狀態 (屬性值) 是從主控模組直接得到指示而確定

的;從控制角度說,它的確處於系統的上層地位。如果採用結構化方法,結果將是要麼把系統結構變成網路狀

,失去結構化特徵,要麼放棄這種統一完成重複性勞動的設計方案。

  其次,應用物件模型向資料庫概念模式的映射設計也是該系統採用物件導向方法的一個標誌。如果使用結

構化方法,資料庫模式可能映射客觀世界的資料結構。由於公路、養路單位、管理單位、路況、橋樑、隧道及

道路上的綠化情況等各實體間客觀存在著複雜的多重關係,其結果可能定義出一個像蜘蛛網似的關係庫結構,

因而大大加重了資料庫前端應用編程和資料庫維護的負擔。

  總之,該系統若使用結構化方法,系統結構和資料庫結構都可能成為網狀結構,且互相無關。而目前採用

的物件導向方法,系統結構和資料庫結構都是多重繼承結構,相互存在映射關係。顯然前者較後者複雜性高、

可維護性差、內部重用難度大、重用率低。

  其實,無論是用什麼方法學開發軟體,交給使用者的都應該是滿足使用者當前需求的軟體。使用者在短期內不會

發現開發人員使用先進方法學給他們帶來的益處,倒是開發人員本身由於大大減輕了開發負擔而最先受益。但是隨

著時間的推移,獲得最大收益的還是使用者,因為軟體的長期品質(包括維護成本低和生存周期長)給使用者帶來

的好處才是根本的。

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

  (1)方法學的目的是:使後人分享前人的成功,避開前人的失敗,把注意力集中在尚未開拓領域的創造性

勞動上。所以方法學與開發人員的創造性是絕不衝突的。它既不能像法律那樣靠權威來界定是非邊界,也不能

像定律那樣通過證明和推理給出普遍結論。如果一定要做比喻的話,它好比人的世界觀。

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

定的方法學。

  例如,物件導向方法的物件模型圖表,這種形式化語言遠不如結構化方法的結構圖和資料流圖簡單明了,倘

若把公路局系統全部用物件模型圖表表述出來,至少也要幾十頁。由於最上層功能模型與物件模型是一致的,所

以我們採用的是結構化方法的系統結構圖。

  (3)事實表明,由 OOP 帶動的 OOSE 方法確實比結構化方法更能自然地抽象現實世界,而且一些 OOP 工

具確實已相當成熟。相反,結構化方法及開放平台下的結構化程式開發工具,雖然不能說止步不前,但其近年

來的進步是有限的。

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

    1 最好在選定方法學後,對全體開發人員進行一次關於物件導向方法學的培訓。
    2 由於有超類對象的提前開發工作,OOSE 的上遊設計工作量比結構化方法的上遊工作負擔重,時間和

人力應該更充足一些。否則到下遊開發後再追加或多次修改變更超類對象,容易造成混亂和無效勞動。
    3 由於系統越大對象類越多,為了便於內部重用和共用,應該建立電子化的對象資料辭典,以便對對

象進行統一歸類管理。
    4 應該有嚴格的命名規則,如果可能,應將命名規則集成到資料辭典中。
    5 下層開發鋪開後,如果發現應該對某些執行個體對象泛化成新的超類對象,必須儘快進行新超類追加的

設計,變更越快越好。
    6 子物件繼承超類對象後,發現超類設計的缺陷是常有的事。開發隊伍內部應有很暢通的反饋渠道,

使超類得到及時的修正。子物件切不可輕易將超類對象封殺掉,使系統失去統一控制。遵從系統設計中定義的

繼承關係進行執行個體對象開發應該成為全體開發人員的理念。
    7 物件導向設計的好處越到後來越顯著,特別是在系統維護和擴充方面。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.