原作:Linda M. Northrop
Software Engineering Institute
翻譯:[AKA] waterbird
1 曆史回顧
針對日趨複雜的軟體需求的挑戰,軟體業界發展出了物件導向(OO)的軟體開發模式。目前作為針對“軟體危機”的最佳對策,OO技術已經引起人們的普遍關注。最初被多數人看作只是一種不切實際的方法和滿足一時好奇心的研究,現在得到了人們近乎狂熱的歡迎。許多程式設計語言都推出了支援物件導向的新版本。大量的物件導向的開發方法被提出來。關於OO的會議、學術研討班和課程極受歡迎。無數專業的學術期刊都為這一話題開闢了專門的版面。一些軟體開發合約甚至也指明了必須使用OO的技術和語言。物件導向的軟體開發對於90年代,就向是結構化的軟體開發對於70年代那樣讓人著迷,而且OO的發展勢頭還在日益加速。
諸如“對象”和“對象的屬性”這樣的概念,可以一直追溯到1950年代初。它們首先出現於關於人工智慧的早期著作中。然而,OO的實際發展卻是始於1966年 (當年文化大革命在中國爆發) 。 當時Kisten Nygaard和Ole-Johan Dahl開發了具有更進階抽象機制的Simula語言。Simula提供了比子程式更高一級的抽象和封裝;為模擬一個實際問題,引入了資料抽象和類的概念。 大約在同一時期,Alan Kay正在尤他大學的一台個人電腦上努力工作,他希望能在其上實現圖形化和類比模擬。儘管由於軟硬體的限制,Kay的嘗試沒有成功,但他的這些想法並沒有丟失。70年代初期,他加入了Palo Alto研究中心(PARC),再次將這些想法付諸實施。
在PARC,他所在的研究小組堅信電腦技術是改善人與人、人與機器之間通訊渠道的關鍵。在這信念的支援下,並吸取了Simula的類的概念,他們開發出Smalltalk語言;1972年PARC發布了Smalltalk的第一個版本。大約在此時,“物件導向”這一術語正式確定。Smalltalk被認為是第一個真正物件導向的語言。 Smalltalk 的目標是為了使軟體設計能夠以儘可能自動化的單元來進行。在Smalltalk中一切都是對象-----即某個類的執行個體。最初的Smalltalk的世界中,對象與名詞緊緊相連。Smalltalk還支援一個高度互動開發環境和原型方法。這一原創性的工作開始並未發表,只是視為帶濃厚實驗性質的學術興趣而已。
Smalltalk-80是PARC的一系列Smalltalk版本的總結,發佈於1981年。1981年8月的<<BYTE>>雜誌公布了Smalltalk開發組的重要結果。在這期雜誌的封面圖上,一個熱氣球正從一個孤島上冉冉升起來,標誌著PARC的物件導向思想的啟航。該是向軟體開發界公開發表的時候了。起初,影響只是漸進式的,但很快就躍升到火爆的程度。熱氣球確實啟航了,而且影響深遠。早期Smalltalk關於開發環境的研究導致了後來的一系列進展:視窗(window),表徵圖(icon),滑鼠(mouse)和下拉式window環境。Smalltalk語言還影響了80年代早期和中期的物件導向的語言,如:Object-C(1986), C++(1986), Self(1987),Eiffl(1987),Flavors(1986). 物件導向的應用領域也被進一步拓寬。對象不再僅僅與名詞相聯絡,還包括事件和過程。1980 Grady Booch首先提出物件導向設計(OOD)的概念。然後其他人緊隨其後,物件導向分析的技術開始公開發表。1985年,第一個商用物件導向資料庫問世。1990年代以來,物件導向的分析、測試、度量和管理等研究都得到長足發展。目前對象技術的前沿課題包括設計模式(design patterns)、分布式對象系統和基於網路的對象應用等。
2 動因
為什麼物件導向運動發展到了現在這樣火暴的程度?部分是源於人們長久以來的一個希望:人們希望它,象以前其他的軟體開發技術一樣,能夠滿足軟體開發對於生產效率、可靠性、易維護性、易管理等方面的更高、更快、更強的迫切需求。除此之外,還有許多原因都促使了它的流行。
物件導向的開發強調從問題域的概念到軟體程式和介面的直接映射;心理學的研究也表明,把客觀世界看成是許多個物件更接近人類的自然思維方式。對象比函數更為穩定;軟體需求的變動往往是功能相關的變動,而其功能的執行者----對象----通常不會有大的變動。另外,物件導向的開發也支援、鼓勵軟體工程實踐中的資訊隱藏、資料抽象和封裝。在一個對象內部的修改被局部隔離。物件導向開發的軟體易於修改、擴充和維護。
物件導向也被擴充應用於軟體生命週期的各個階段---從分析到編碼。而且,物件導向的方法自然而然地支援快速原型法和RAD(Rapid Application Development)。物件導向開發的使用鼓勵重用,不僅軟體的重用,還包括分析、設計的模型的重用。更進一步,OO技術還方便了軟體的互換性,即,網路中一個節點上應用能夠利用另一個節點上的資源。物件導向的開發還支援並發、層次和複雜等一些在目前的軟體系統中常見的現象。今天我們常常會需要建造一些軟體系統----不止是一黑盒應用。這些複雜系統通常包含由多個子系統組成的階層。物件導向的開發支援開放系統的建設;利用不同的應用來進行軟體整合有了更大的柔性。最後,物件導向開發的使用可以減小開發複雜系統所面臨的危險,主要是因為系統整合遍布軟體生命週期的各個階段。
3 物件導向的建模
物件導向的建模不僅僅是新的程式設計語言的匯總。它是一種新的思維方式,一種關於計算和資訊結構化的新思維。物件導向的建模,把系統看做是相互協作的對象,這些對象是結構和行為的封裝,都屬於某個類,那些類具有某種層次化的結構。系統的所有功能通過對象之間相互發送訊息來獲得。物件導向的建模可以視為是一個包含以下元素的概念架構:抽象、封裝、模組化、層次、分類、並行、穩定、可重用和可擴充性。
物件導向的建模的出現並不能算是一場計算革命。更恰當地講,它是面向過程和嚴格資料驅動的軟體開發方法的漸進演變結果。軟體開發的新方法受到來自兩個方面的推動:程式設計語言的發展和日趨複雜的問題域的需求驅動。儘管在實際中分析和設計在編程階段之前進行,但從發展曆史看卻是程式設計語言的革新帶來設計和分析技術的改變。同樣,語言的演變也是對電腦體系的增強和需求的日益複雜的自然響應。
影響OO產生的諸多因素中,最重要的可能要算是編程方法的進步了。在過去的幾十年中,程式設計語言中對抽象機制的支援已經發展到了一個較高的水平。這種抽象的進化從地址(機器語言)到名字(組合語言),到運算式(第一代進階語言,如Fortran),到控制(第二代進階語言,如Cobol),到過程和函數(第二代和早期第三代進階語言,如Pascal),到模組和資料(晚期第三代進階語言,如modula),最後到對象(基於對象和物件導向的語言)。Smalltalk和其他物件導向語言的發展使得新的分析和設計的技術的實現成為可能。
這些新的OO的技術實際上是結構化和資料庫方法的融合。OO的方法中,小範圍內對面向資料流的關注,如偶合和彙總,也是很重要的。同樣,對象內部的行為最終也需要面向過程的設計方法。資料庫技術中的實體-關係(ER圖)的資料建模思想也在 OO的方法中得以體現。
電腦硬體體繫結構的進步,效能價格比的提高和硬體設計中對象概念的引入都對OO的發展產生了一定的影響。OO的程式通常要更加頻繁地訪問記憶體,需要更高的處理速度。他們需要並且也正在利用強大的電腦硬體功能。哲學和認知科學的層次和分類理論也促進了OO的產生和發展。最後,電腦系統不斷增長的規模、複雜度和分布性都對OO技術起了或多或少的推動作用。
因為影響OO發展的因素很多,OO技術本身還未成熟,所以在思想和術語上有很多不同的提法。所有的OO語言並非生而平等,他們在術語、概念的運用上也各不相同。儘管也存在統一的趨勢,但就如何進行物件導向的分析、設計而言還沒有完全達成共識,更沒有統一的符號來描述這些活動。(說明:UML正在朝這方向努力) 但是,OO的開發已經在以下領域被證明是成功的:空中交通管理、動畫設計、銀行、商業資料處理、命令和控制系統、CAD、CIM、資料庫、專家系統、圖象識別、數學分析、音樂合成、作業系統、過程式控制制、空間站軟體、機器人、遠程通訊、介面設計和VLSI設計。毫無疑問,OO技術的應用已經成為軟體工業發展的主流。
4 物件導向編程
<1> 概念
在物件導向編程中,程式被看作是相互協作的對象集合,每個對象都是某個類的執行個體,所有的類構成一個通過繼承關係相聯絡的階層。物件導向的語言常常具有以下特徵:對象產生功能、訊息傳遞機制、類和遺傳機制。這些概念當然可以並且也已經在其他程式設計語言中單獨出現,但只有在物件導向語言中,他們才共同出現,以一種獨特的合作方式互相協作、互相補充。
過程化編程模式: 參數輸入----- | 代 碼 | ------結果輸出
為實現某個功能,參數被傳入某個處理過程,最後傳回計算結果。
| 對象------ 資料結構 物件導向編程模式:
介面 | 對象------ 和
| 對象------ 操作
OOP中,功能是通過與對象的通訊獲得的。對象可以被定義為一個封裝了狀態和行為的實體;或者說是資料結構(或屬性)和操作。狀態實際上是為執行行為而必須存於對象之中的資料、資訊。對象的介面,也可稱之為協議,是一組對象能夠響應的訊息的集合。 訊息是對象通訊的方式,因而也是獲得功能的方式。對象受到發給他的訊息後,或者執行一個內部操作(有時成為方法或過程),或者再去調用其他對象的操作。所有對象都是類的執行個體。類是具有相同特點的對象的集合,或者也可以說,類是可用於產生對象的一個模版。對象響應一個訊息而調用的方法,由接受該訊息的對象自己決定。 類可以以一種階層來安排。在這個階層中,子類可以從比他高的超類中繼承得到狀態和方法。當對象接收到一個訊息後,尋找相應的方法的過程將在從該對象的類開始,並在該類所處的階層中展開,最後,直到找著該方法,或者什麼也沒找到(將會報錯)。在某些語言中,一個給定的類可以從不止一個超類中繼承,稱之為多繼承。如果採用動態聯編,繼承就導致了多態性。多態性描述的是如下現象:如果幾個子類都重新定義了超類的某個函數(都用相同的函數名),當訊息被發送到一個子類對象時,在執行時該訊息會由於子類確定的不同而被解釋為不同的操作。 方法也可以被包括在超類的介面中被子類繼承,而實際上並不去真正定義他。這樣的超類也叫抽象類別。抽象類別不能被執行個體化,因此也就只能被用於產生子類。
<2> 語言
物件導向的語言套件含4個基本的分支:
1 基於Smalltalk的; 包括smalltalk的5個版本,以Smalltalk-80為代表。
2 基於C的; 包括 objective-C, C++, Java
3 基於LISP的; 包括 Flavors, XLISP, LOOPS, CLOS
4 基於PASCAL的。包括 Object Pascal, Turbo Pascal, Eiffel, Ada 95
Simula實際上是所有這些語言的老祖宗。在這些OO語言中,術語的命名和支援OO的能力都有不同程度的差別。 儘管Smalltalk-80不支援多繼承,它仍被認為是最物件導向的語言(the truest OO language)。
在基於C的OO語言中,Object-C 是Brad Cox開發的,它帶有一個豐富的類庫,已經被成功用於大型系統的開發。C++是由貝爾實驗室的Bjarne Stroustrup寫的。它將C語言中的STRUCT 擴充為 具有資料隱藏功能的CLASS。多態性通過虛函數(virtual functions)來實現。C++ 2.0 支援多繼承。在多數軟體領域,尤其是Unix平台上,C++都是首選的物件導向程式設計語言。 同C和C++相類似的新一代基於Internet的物件導向語言Java是由Sun microsystems研製的。它於1995年伴隨著Internet的崛起而風靡一時。用Java寫的applets可以嵌入HTML中被解釋執行,這使它具備了跨平台特性。Java和Ada一樣支援多線程和並發機制,又象C一樣簡單、便攜。
基於LISP的語言,多被用於知識表達和推理的應用中。其中CLOS(Common LISP Object System)是物件導向LISP的標準版。
在基於Pascal的語言中,Object Pascal是由Apple和Niklaus Wirth為Macintosh開發的,它的類庫是MacApp。Turbo Pascal 是Borland公司以Object Pascal為範本開發的。
Eiffel由互動軟體工程公司的Bertrand Meyer於1987年發布的。它的文法類似Ada,運行於Unix環境。Ada在1983年剛出來時並不支援繼承和多態性,因而不是物件導向的。到了1995年,一個物件導向的Ada終於問世,這就是Ada 95。
除了上述的物件導向的語言之外,還有一些語言被認為是基於對象(Object-based)的。它們是:Alphard, CLU, Euclid, Gypsy, Mesa, Modula。
5 物件導向的軟體工程
生命週期
儘管物件導向的語言正在取得令人激動的進展,但我們都知道,編碼並非是軟體開發中的問題的主要來源。相比之下,需求和分析的問題更加普遍,而且它們的錯誤修正代價更加昂貴。因此, 對OO開發技術的關注就不能僅僅集中在編碼上面,更應集中關心軟體工程的其他方面。OO方法在處理複雜系統的分析和設計、分析和設計的重用方面的應用前景也是非常可觀。如果我們承認OO的軟體開發不僅僅局限於編碼活動,那麼就必須採用一種全新的開發模式,包括新的軟體生命週期。 目前最常見的生命週期是“瀑布”模型(結構化)。它是在60年代末“軟體危機”後出現的第一個生命週期模型。如下所示。
分析 ----- 設計 ----- 編碼 ----- 測試 ------ 維護
,瀑布式生命週期的開發過程是順序行進的;活動流向基本是單向的。它假設開發人員在開發初期對系統的瞭解足夠清楚。不幸的是,任何軟體開發活動都不可避免地要涉及大量迭代過程,無論你事先是否安排。好的設計人員指的是那些能同時在抽象的層面和具體的細節上進行工作的實踐家。總的來說,瀑布式生命週期的缺點表現在三個方面:<1> 後期的變化、迭代、改動困難 <2> 不支援重用 <3> 沒有一個聯絡各個階段的統一模型。
物件導向的方法從問題模型開始,然後就是識別對象、不斷細化的過程。它從本質上就是迭代的和漸增的。在這裡,快速原型和反饋環路是必需的標準結構。開發過程就是一次次的迭代反覆過程。隨著迭代的進行,系統的功能不斷完善。這裡,傳統的開發模式中在分析、設計和編碼等各個階段之間的明顯界限變得模糊起來。其原因是因為對象的概念瀰漫了整個開發過程。對象和它們之間的關係成為分析、設計和編碼等各個階段的共同表達媒介。開發的重心從編碼向分析位移,從功能為中心向資料為中心位移。而且,物件導向開發的迭代和無縫性使得重用變得更加自然。
近來,為改善物件導向開發的可管理性,玻姆(Boehm,1988)提出了一個結合了宏觀和微觀視角(macro & microview)的螺旋開發模型。宏觀包括3個階段:1分析---發現和識別對象;2 設計---發明和設計對象;3 實施---建立和實現對象。每個宏觀階段都包含一些微觀迭代活動。
6 OOA和OOD
由於物件導向的技術還比較新,目前存在許多種物件導向的分析和設計方法。物件導向的分析(OOA)建立於以前的資訊建模技術的基礎之上,可以定義為是一種以從問題域詞彙中發現的類和對象的概念來考察需求的分析方法。OOA的結果是一系列從問題域匯出的“黑箱”對象。OOA通常使用“劇情(scenarios)”來協助確定基本的對象行為。一個劇情是發生在問題域的一個連續的活動序列。在對一個給定的問題域進行 OOA時,“架構”(Frameworks)的概念非常有用。架構是應用或應用子系統的骨架,包含一些具體或者抽象的類。或者說,架構是一個特定的階層,包含描述某一問題域的抽象父類。當下流行的所有的OOA方法的一個缺點就是他們都缺乏一種固定的模式(formality)。
在物件導向的設計(OOD)階段,注意的焦點從問題空間轉移到瞭解空間。OOD是一種包含對所設計系統的邏輯的和物理的流程說明,以及系統的靜態和動態模型的設計方法(Booch,1994)。
在OOA和OOD中,都存在著對重用性的關注。目前,OO技術的研究人員們正在嘗試定義“設計模式(design patterns)”這一概念。它是一種可重用的“財富”,可以應用於不同的問題域。通常,設計模式指的是一種多次出現的設計結構或解決方案。如果對他們進行系統的歸類,即可被重用,可以構成不同設計之間通訊的基礎。
OOD技術實際上早於OOA技術而出現。目前在OOA和OOD已經很難畫出一條清晰的界限。因此,下面的描述給出一些常用的OOA/OOD技術的(聯合)概貌。
Meyer 用語言作為表達設計的工具。(1988)
Booch的OOD技術擴充了他以前在Ada方面的工作。他採用一種“反覆綜合(round-trip gestalt)”的方法,包括以下過程:識別對象,識別對象的語義,識別對象之間的關係,進行實施,同時包含一系列迭代。Booch是最先使用類圖,類分類圖,類模板和對象圖來描述OOD的人(1991)。
Wrifs-Brock's的OOD技術是由職責代理來驅動的。類職責卡(Class Responsibilities Cards)被用來記錄負責特定功能的類。在確定了類及其職責之後,再進行更詳細的關係分析和子系統的實施。(1990)
Rumbaugh使用3種模型來描述一個系統:1 物件模型,描述系統中對象的靜態結構;2 動態模型,描述系統狀態隨時間變化的情況;3 功能模型,描述系統中各個資料值的轉變。對象圖,狀態轉換圖和資料流圖分別被用於描述這3個模型。(1991)
Coad和Yourdon採用以下的OOA步驟來確定一個多層OO模型(5個層次):找出類和對象,識別結構和關係,確定主題,定義屬性,定義服務。5個步驟分別對應模型的5個層次,即類和對象層,主題層,結構層,屬性層和服務層。他們的OOD方法既是多層次的又是多方面的(multicomponent)。層次機構和OOA一樣。多方麵包括:問題域,人與人的互動,任務管理和資料管理。
Ivar Jacobson 提出了Objectory方法(或Jacbson法),一種他在瑞典Objective系統中開發的物件導向軟體工程方法。Jacbson的方法特彆強調了“Use Case”的使用。 Use Case成為分析模型的基礎,用互動圖(Interaction Diagram)進一步描述後就形成設計的模型。Use cases同時也驅動測試階段的測試工作。到目前為止,Jacbson法是最為完整的工業方法。 (1992)
以上所述的方法還有許多的變種,無法一一列出。近年來,隨著各種方法的演變,它們之間也互相融合。1995年,Booch,Rumbaugh和Jacbson聯手合作,提出了第一版的UML(Unified Modelling Language),一體化建模語言。(目前已經成為OO建模語言的事實標準)
7 管理問題
當組織向物件導向的開發技術轉向時,支援軟體開發的管理活動也必然要有所改變。承諾使用OO技術即意味要改變開發過程,資源和組織圖。(Goldberg 1995) OO開發的迭代、原型以及無縫性消除了傳統開發模式不同階段之間的界限。新的界限必須被重新確定。同時,一些軟體測度的方法也不在適用了。“程式碼數”LOC(Lines of Code)絕對過時了。重用類的數目,繼承層次的深度,類與類之間關係的數目,對象之間的耦合度,類的個數以及大小顯得更有意義。在OO的軟體測度方面的工作還是相當新的,但也已經有了一些參考文獻。(Lorenz 1993)
資源分派和人員配置都需要重新考慮。開發小組的規模逐步變小,擅長重用的專家開始吃香。重點應該放在重用而非LOC上。重用的真正實現需要一套全新的準則。在執行軟體合約的同時,庫和應用程式框架也必須建立起來。長期的投資策略,以及對維護這些可重用財富的承諾和過程,變的更加重要。
至於軟體品質保證,傳統的測試活動仍是必須的,但它們的計時和定義必須有所改變。例如,將某個功能“走一遍”將牽涉到啟用一個劇情(scenario),一系列對象互相作用,發送訊息,實現某個特定功能。測試一個OO系統是另一個需要進一步研究的課題。發布一個穩定的原型需要不同與以往控制結構化開發的產品的組態管理。
另一個管理方面要注意的問題是合適的工具支援。一個物件導向的開發環境是必須的。同時需要的還包括:一個類庫瀏覽器,一個漸增型編譯器,支援類和對象語義的調試器,對設計和分析活動的圖形化支援和引用檢查,組態管理和版本控制工具,以及一個象類庫一樣的資料庫應用。
除非物件導向開發的曆史足以提供有關資源和消耗的資料,否則成本估算也是一個問題。計算公式中應該加入目前和未來的重用成本。最後,管理也必須明白在向物件導向方法轉變的過程中要遇到的風險。如訊息傳遞、訊息傳遞的爆炸增長、動態記憶體分配和釋放的代價。還有一些起步風險,如對合適的工具,開發戰略的熟悉,以及適當的培訓,類庫的開發等。
8 向物件導向轉變
這個轉變的時期可能相當長。培訓是必須的。一個實驗性質的嚮導項目也是有必要的。建議不要使用結構化和物件導向像結合的辦法。越來越多的證據表明,成功需要完全的 OO解決方案.
9 未來
總的來說,物件導向的技術是以前的軟體開發技術自然演化的成果,對許多應用領域的軟體開發都極具前途。借用Maurice Wilkes在他圖靈獎頒獎儀式上的演講的話:“對象是軟體界從70年代以來最激動人心的革新之一。” (1996) 然而,物件導向的開發並非是包醫百病的靈丹妙藥,其發展還遠未成熟。可是儘管OO技術的未來還未確定,但在90年代初期的一些預言都已實現。(Winblad 1990) 類庫和應用程式架構在市場上已經可用。應用和環境之間的透明資訊存取業已實現。支援使用者在應用之間通訊的的環境以及物件導向的繼承多媒體工具包正在湧現。隨著經驗的積累,OO的發展將日漸流行,OO技術也將日趨成熟。當然,OO技術也有可能為某種處理更高一級抽象的開發技術取代或融合。這些都只是猜想。雖然在不遠的將來,談論對象無疑會顯得過時,但現在,還有許多的問題等著我們去付出真正的熱情。