java面向對象OOA、OOD、OOP

OOA:Object-Oriented Analysis面向對象分析方法

是在一個系統的開發過程中進行了系統業務調查以后,按照面向對象的思想來分析問題。OOA與結構化分析有較大的區別。OOA所強調的是

在系統調查資料的基礎上,針對OO方法所需要的素材進行的歸類分析和整理,而不是對管理業務現狀和方法的分析。

OOA(面向對象的分析)模型由5個層次(主題層、對象類層、結構層、屬性層和服務層)和5個活動(標識對象類、標識結構、定義主題

、定義屬性和定義服務)組成。在這種方法中定義了兩種對象類之間的結構,一種稱為分類結構,一種稱為組裝結構。分類結構就是所謂的一

般與特殊的關系。組裝結構則反映了對象之間的整體與部分的關系。

OOA在定義屬性的同時,要識別實例連接。實例連接是一個實例與另一個實例的映射關系。

OOA在定義服務的同時要識別消息連接。當一個對象需要向另一對象發送消息時,它們之間就存在消息連接。

OOA 中的5個層次和5個活動繼續貫穿在OOD(畫向對象的設計)過程中。OOD模型由4個部分組成。它們分別是設計問題域部分、設計人機

交互部分、設計任務管理部分和設計數據管理部分。

一、OOA的主要原則:

(1)抽象:從許多事物中舍棄個別的、非本質的特征,抽取共同的、本質性的特征,就叫作抽象。抽象是形成概念的必須手段。

抽象原則有兩方面的意義:第一,盡管問題域中的事物是很復雜的,但是分析員并不需要了解和描述它們的一切,只需要分析研究其中與

系統目標有關的事物及其本質性特征。第二,通過舍棄個體事物在細節上的差異,抽取其共同特征而得到一批事物的抽象概念。

抽象是面向對象方法中使用最為廣泛的原則。抽象原則包括過程抽象和數據抽象兩個方面。

過程抽象是指,任何一個完成確定功能的操作序列,其使用者都可以把它看作一個單一的實體,盡管實際上它可能是由一系列更低級的操

作完成的。

數據抽象是根據施加于數據之上的操作來定義數據類型,并限定數據的值只能由這些操作來修改和觀察。數據抽象是OOA的核心原則。它

強調把數據(屬性)和操作(服務)結合為一個不可分的系統單位(即對象),對象的外部只需要知道它做什么,而不必知道它如何做。

(2)封裝就是把對象的屬性和服務結合為一個不可分的系統單位,并盡可能隱蔽對象的內部細節。

(3)繼承:特殊類的對象擁有的其一般類的全部屬性與服務,稱作特殊類對一般類的繼承。

在OOA中運用繼承原則,就是在每個由一般類和特殊類形成的一般—特殊結構中,把一般類的對象實例和所有

特殊類的對象實例都共同具

有的屬性和服務,一次性地在一般類中進行顯式的定義。在特殊類中不再重復地定義一般類中已定義的東西,但是在語義上,特殊類卻自動地

、隱含地擁有它的一般類(以及所有更上層的一般類)中定義的全部屬性和服務。繼承原則的好處是:使系統模型比較簡練也比較清晰。

(4)分類:就是把具有相同屬性和服務的對象劃分為一類,用類作為這些對象的抽象描述。分類原則實際上是抽象原則運用于對象描述

時的一種表現形式。

(5)聚合:又稱組裝,其原則是:把一個復雜的事物看成若干比較簡單的事物的組裝體,從而簡化對復雜事物的描述。

(6)關聯:是人類思考問題時經常運用的思想方法:通過一個事物聯想到另外的事物。能使人發生聯想的原因是事物之間確實存在著某

些聯系。

(7)消息通信:這一原則要求對象之間只能通過消息進行通信,而不允許在對象之外直接地存取對象內部的屬性。通過消息進行通信是

由于封裝原則而引起的。在OOA中要求用消息連接表示出對象之間的動態聯系。

(8)粒度控制:一般來講,人在面對一個復雜的問題域時,不可能在同一時刻既能縱觀全局,又能洞察秋毫。因此需要控制自己的視野

:考慮全局時,注意其大的組成部分,暫時不詳察每一部分的具體的細節;考慮某部分的細節時則暫時撇開其余的部分。這就是粒度控制原則

(9)行為分析:現實世界中事物的行為是復雜的。由大量的事物所構成的問題域中各種行為往往相互依賴、相互交織。

二、面向對象分析產生三種分析模型:

1、對象模型:對用例模型進行分析,把系統分解成互相協作的分析類,通過類圖/對象圖描述對象/對象的屬性/對象間的關系,是系統的靜態

模型

2、動態模型:描述系統的動態行為,通過時序圖/協作圖描述對象的交互,以揭示對象間如何協作來完成每個具體的用例,單個對象的狀態變

化/動態行為可以通過狀態圖來表達

3、功能模型(即用例模型à作為輸入)。

三、OOA的主要優點:

(1)加強了對問題域和系統責任的理解;

(2)改進與分析有關的各類人員之間的交流;

(3)對需求的變化具有較強的適應性;

(4)支持軟件復用。

(5)貫穿軟件生命周期全過程的一致性。

(6)實用性;

(7)有利于用戶參與。

四、OOA方法的基本步驟:

在用OOA具體地分析一個事物時,大致上遵循如下五個基本步驟:

第一步,確定對象和類。這里所說的對象是對數據及其處理方式的抽象,它反映了系統保存和處理現實世界中某些事物的信息的能力。類

是多個對象的共同屬性和方

法集合的描述,它包括如何在一個類中建立一個新對象的描述。

第二步,確定結構(structure)。結構是指問題域的復雜性和連接關系。類成員結構反映了泛化-特化關系,整體-部分結構反映整體和

局部之間的關系。

第三步,確定主題(subject)。主題是指事物的總體概貌和總體分析模型。

第四步,確定屬性(attribute)。屬性就是數據元素,可用來描述對象或分類結構的實例,可在圖中給出,并在對象的存儲中指定。

第五步,確定方法(method)。方法是在收到消息后必須進行的一些處理方法:方法要在圖中定義,并在對象的存儲中指定。對于每個對

象和結構來說,那些用來增加、修改、刪除和選擇一個方法本身都是隱含的(雖然它們是要在對象的存儲中定義的,但并不在圖上給出),而

有些則是顯示的。

OOP

目錄[隱藏]

一、OOP的基本思想

二、OOP技術的歷史

三、OOP 的優缺點

四、OOP的未來

五、不同OOP語言各有什么優勢和劣勢?

六、發展 vs. 革新

OOP: Object Oriented Programming,面向對象的程序設計

所謂“對象”就是一個或一組數據以及處理這些數據的方法和過程的集合。面向對象的程序設計完全不同于傳統的 面向過程程序設計,它大大地降低了軟件開發的難度,使編程就像搭積木一樣簡單,是當今電腦編程的一股勢不可擋的潮流。

面向對象編程(Object Oriented Programming,OOP,面向對象程序設計)是一種計算機編程架構。OOP 的一條基本原則是計算機程序是由單個能夠起到子程序作用的單元或對象組合而成。OOP 達到了軟件工程的三個主要目標:重用性、靈活性和擴展性。為了實現整體運算,每個對象都能夠接收信息、處理數據和向其它對象發送信息。OOP 主要有以下的概念和組件:

組件 - 數據和功能一起在運行著的計算機程序中形成的單元,組件在 OOP 計算機程序中是模塊和結構化的基礎。

抽象性 - 程序有能力忽略正在處理中信息的某些方面,即對信息主要方面關注的能力。

封裝 - 也叫做信息封裝:確保組件不會以不可預期的方式改變其它組件的內部狀態;只有在那些提供了內部狀態改變方法的組件中,才可以訪問其內部狀態。每類組件都提 供了一個與其它組件聯系的接口,并規定了其它組件進行調用的方法。

多態性 - 組件的引用和類集會涉及到其它許多不同類型的組件,而且引用組件所產生的結果得依據實際調用的類型。

繼承性 - 允許在現存的組件基礎上創建子類組件,這統一并增強了多態性和封裝性。典型地來說就是用類來對組件進行分組,而且還可以定義新類為現存的類的擴展,這樣就 可以將

類組織成樹形或網狀結構,這體現了動作的通用性。

由于抽象性、封裝性、重用性以及便于使用等方面的原因,以組件為基礎的編程在腳本語言中已經變得特別流行。Python 和 Ruby 是最近才出現的語言,在開發時完全采用了 OOP 的思想,而流行的 Perl 腳本語言從版本5開始也慢慢地加入了新的面向對象的功能組件。用組件代替“現實”上的實體成為 JavaScript(ECMAScript)得以流行的原因,有論證表明對組件進行適當的組合就可以在英特網上代替 HTML 和 XML 的文檔對象模型(DOM)。

[編輯本段]

一、OOP的基本思想

OOP的許多原始思想都來之于Simula語言,并在Smalltalk語言的完善和標準化過程中得到更多的擴展和對以前的思想的重新注解。可以說 OO 思想和OOPL幾乎是同步發展相互促進的。與函數式程序設計(functional-programming)和邏輯式程序設計(logic- programming)所代表的接近于機器的實際計算模型所不同的是,OOP幾乎沒有引入精確的數學描敘,而是傾向于建立一個對象模型,它能夠近似的反 映應用領域內的實體之間的關系,其本質是更接近于一種人類認知事物所采用的哲學觀的計算模型。由此,導致了一個自然的話題,那就是OOP到底是什么? [D&T 1988][B.S 1991] .。在OOP中,對象作為計算主體,擁有自己的名稱,狀態以及接受外界消息的接口。在對象模型中,產生新對象,舊對象銷毀,發送消息,響應消息就構成 OOP計算模型的根本。

對象的產生有兩種基本方式。一種是以原型(prototype)對象為基礎產生新的對象。一種是以類(class)為基礎產生新對象。原型的概念已經 在認知心理學中被用來解釋概念學習的遞增特性,原型模型本身就是企圖通過提供一個有代表性的對象為基礎來產生各種新的對象,并由此繼續產生更符合實際應用 的對象。而原型-委托也是OOP中的對象抽象,代碼共享機制中的一種。一個類提供了一個或者多個對象的通用性描敘。從形式化的觀點看,類與類型有關,因此 一個類相當于是從該類中產生的實例的集合。而這樣的觀點也會帶來一些矛盾,比較典型的就是在繼承體系下,子集(子類)對象和父集(父類)對象之間的行為相 融性可能很難達到,這也就是OOP中常被引用的---子類型(subtype)不等于子類(subclass)[Budd 2002]。而在一種所有皆對象的世界觀背景下,在類模型基礎上還誕生出了一種擁有元類(metaclass)的新對象模型。即類本身也是一種其他類的對 象。以上三種根本不同的觀點各自定義了三種基于類(class-based),基于原型(prototype-based)和基于元類 (metaclass-based)的對象模型。而這三種對象模型也就導致了許多不同的

程序設計語言(如果我們暫時把靜態與動態的差別放在一邊)。是的, 我們經常接觸的C++,Java都是使用基于類的對象模型,但除此之外還有很多我們所沒有接觸的OOPL采用了完全不一樣的對象模型,他們是在用另外一種 觀點詮釋OOP的內涵。

什么是oop的基本思想呢?把組件的實現和接口分開,并且讓組件具有多態性。不過,兩者還是有根本的不同。oop強調在程序構造中語言要素的語法。你 必須得繼承,使用類,使用對象,對象傳遞消息。gp不關心你繼承或是不繼承,它的開端是分析產品的分類,有些什么種類,他們的行為如何。就是說,兩件東西 相等意味著什么?怎樣正確地定義相等操作?不單單是相等操作那么簡單,你往深處分析就會發現“相等”這個一般觀念意味著兩個對象部分,或者至少基本部分是 相等的,據此我們就可以有一個通用的相等操作。再說對象的種類。假設存在一個順序序列和一組對于順序序列的操作。那么這些操作的語義是什么?從復雜度權衡 的角度看,我們應該向用戶提供什么樣的順序序列?該種序列上存在那些操作?那種排序是我們需要的?只有對這些組件的概念型分類搞清楚了,我們才能提到實現 的問題:使用模板、繼承還是宏?使用什么語言和技術?gp的基本觀點是把抽象的軟件組件和它們的行為用標準的分類學分類,出發點就是要建造真實的、高效的 和不取決于語言的算法和數據結構。當然最終的載體還是語言,沒有語言沒法編程。stl使用 c++,你也可以用ada來實現,用其他的語言來實現也行,結果會有所不同,但基本的東西是一樣的。到處都要用到二分查找和排序,而這就是人們正在做的。 對于容器的語義,不同的語言會帶來輕微的不同。但是基本的區別很清楚是gp所依存的語義,以及語義分解。例如,我們決定需要一個組件swap,然后指出這 個組件在不同的語言中如果工作。顯然重點是語義以及語義分類。而oop所強調的(我認為是過分強調的)是清楚的定義類之間的層次關系。oop告訴了你如何 建立層次關系,卻沒有告訴你這些關系的實質。

(這段不太好理解,有一些術語可能要過一段時間才會有合適的中文翻譯——譯者)

面向對象的編程方法OOP是九十年代才流行的一種軟件編程方法。它強調對象的“抽象”、“封裝”、“繼承”、“多態”。我們講程序設計是由“數據結 構”+“算法”組成的。從宏觀的角度講,OOP下的對象是以編程為中心的,是面向程序的對象。我們今天要講的OOD是面向信息的對象,是以用戶信息為中心 的。

[編輯本段]

二、OOP技術的歷史

面向對象技術最初是從面向對

象的程序設計開始的,它的出現以60年代simula語言為標志。80年代中后期,面向對象程序設計逐漸成熟,被計算機界 理解和接受,人們又開始進一步考慮面向對象的開發問題。這就是九十年代以Microsoft Visual系列OOP軟件的流行的背景。

傳統的結構化分析與設計開發方法是一個線性過程,因此,傳統的結構化分析與設計方法要求現實系統的業務管理規范,處理數據齊全,用戶能全面完整地其業 務需求。

傳統的軟件結構和設計方法難以適應軟件生產自動化的要求,因為它以過程為中心進行功能組合,軟件的擴充和復用能力很差。

對象是對現實世界實體的模擬,因面能更容易地理解需求,即使用戶和分析者之間具有不同的教育背景和工作特點,也可很好地溝通。

區別面向對象的開發和傳統過程的開發的要素有:對象識別和抽象、封裝、多態性和繼承。

對象(Object)是一個現實實體的抽象,由現實實體的過程或信息牲來定義。一個對象可被認為是一個把數據(屬性)和程序(方法)封裝在一起的實 體,這個程序產生該對象的動作或對它接受到的外界信號的反應。這些對象操作有時稱為方法。對象是個動態的概念,其中的屬性反映了對象當前的狀態。

類(Class)用來描述具有相同的屬性和方法的對象的集合。它定義了該集合中每個對象所共有的屬性和方法。對象是類的實例。

由上分析不難看出,盡管OOP技術更看中用戶的對象模型,但其目的都是以編程為目的的,而不是以用戶的信息為中心的,總想把用戶的信息納入到某個用戶 不感興趣的“程序對象”中。

[編輯本段]

三、OOP 的優缺點

· OOP 的優點:使人們的編程與實際的世界更加接近,所有的對象被賦予屬性和方法,結果編程就更加富有人性化。

· OOP 的也有缺點,就 C++ 而言,由于面向更高的邏輯抽象層,使得 C++ 在實現的時候,不得不做出性能上面的犧牲,有時候甚至是致命的 ( 所有對象的屬性都經過內置多重指針的間接引用是其性能損失的主要原因之一;不過,筆者的局限性在于未使用過 VC++ 外的面向對象語言,所以不是十分肯定,哈哈,有人笑出來了… )。

在計算機速度飛速發展的今天,你可能會說,一丁點的性能犧牲沒什么大不了。是的,從面向對象的角度,使的編程的結構更加清晰完整,數據更加獨立和易于 管理,性能的犧牲可以帶來這么多的好處,沒有理由不做穩賺的生意吧?

不過,在某些對速度要求極高特殊場合,例如你做的是電信的交換系統,每秒鐘有超過百萬的人同時進行電話交換,如果,每一個數據交換過程都是一個對象, 那么總的性能損失將是天文數字!!

或者這個例子不夠貼身,再舉個例子吧。假如你受聘于一個游戲設計公司,老板希望做出來的游戲可以更多的兼顧到更多的電腦使用者,游戲每秒鐘的運行的幀 可以更多,子彈和爆炸物可以更多、更華麗。那么,你會發現使用 C++ 會使你的程序變得笨拙,無法滿足你的需求,除非你非得要你的游戲運行于奔騰四的機器上 ( 如果不是,而你又堅持用 C++ 的對象編程,那么請減少主角的槍的威力吧 )。

如果你是冥頑不寧的人,你說不相信 OOP 會有性能上的損失,那么,我記得曾看到在 CSDN 上關于 VB 和 VC 執行效率的討論的文章,講述的就是使用了 MFC 以后,執行效率甚至低于 VB 開發出來的東西。請各位驗證一下:如果使用的是純粹的 C 語言語法的話,那么一定會比在 VB 編出來的東西要快很多 ( GetTickCount 函數可以查閱 MSDN ,如果想更加精確一些,可以使用 QueryPerformanceCounter 函數 )。

[編輯本段]

四、OOP的未來

(撰文/Bjarne Stroustrup & Tim Lindholm 編譯/孟巖)

在未來三年,程序員編寫代碼的方式會發生那些變化?

Stroustrup: 在C++中,假如沒有合適的庫在背后支撐,完成任何重要的工作都可能是很復雜的。而一旦有了合適的庫,任何東西都可以被我們操控于股掌之間。因此,構造和 使用程序庫的重要性與日俱增。這也暗示我們,泛型程序設計(generic programming)將會越來越多地被運用。只有通過GP,我們才能確保庫的通用性和高效率。我還預期在分布式計算和“組件 (components)”應用領域會出現喜人的增長。就大部分程序員而言,通過使用方便適用的程序庫,這些開發工作會變得簡單明了。

現在有一個趨勢,編譯器廠商試圖把其特有的“對象模型”和圖形界面(GUI)細節推銷給用戶。比如微軟的COM和Inprise的類屬性 “properties”。對于用戶來說,這既不必要,也不情愿。我所希望看到的程序庫,應該是用標準C++打造,界面靈活,值得信賴的程序庫。通常,這 些界面應該是平臺無關的。C++的表達能力極強,即使不使用大量的宏,也應該足以達成這一要求。就算有些地方無法百分之百的遵守這一原則,也應該將對于平 臺和廠家的依賴性限制起來。這個目標的完成情況,可以反映軟件工具產業對于應用程序開發行業的關注程度。我懷疑目前對于那些獨立的、跨平臺廠商來說,并不 存在相應的市場。如果能夠建立這樣的市場,也許能夠促進廠商們為客戶做出“真正有用的”產品。

Lindholm: 對于編寫代碼的開發者來說,主要的驅動力量仍將是兩個:網絡和分布式——也就是設計和開發非單機軟件的需求。大部分的應用程序將不會是孤零零地運行在單一 設備上

,而是運用了類似EJB和JSP之類技術的,平臺無關的分布式程序。程序員們將不得不面對分布式計算的重重險阻。這將對許多程序員所依賴的設計模 式、技術和直覺構成嚴峻的挑戰。這是選擇編程語言之前必須認識到的,盡管不同語言的設計特性可能促進或者阻礙這一轉化。

在網絡應用的增長中,一個很重要的部分是小型移動設備和特殊Internet設備的爆炸性增長。這些設備各有各的操作系統,或者只在某種特定的設備領 域內有共同的操作系統。我們現在還可以一一列舉出這些設備——家庭接入設備、蜂窩電話、電子報紙、PDA、自動網絡設備等等。但是這些設備領域的數量和深 入程度將會很快變得難以估量。我們都知道這個市場大得驚人,PC的興起與之相比不過小菜一碟。因此在這些設備的應用程序市場上,競爭將會相當殘酷。獲勝的 重要手段之一,就是盡快進入市場。開發人員需要優秀的工具,迅速高效地撰寫和調試他們的軟件。平臺無關性也是制勝秘訣之一,它使得程序員能夠開發出支持多 種設備平臺的軟件。

我預期的另一個變化是,我們對于代碼(Java)和數據(XML)協同型應用程序的開發能力將會不斷提高。這種協同是開發強大應用程序的核心目標之 一。我們從XML的迅速流行和ebXML規范的進展中,已經看到了這個趨勢。ebXML是一個針對電子商務和國際貿易的,基于XML的開放式基礎構架,由 聯合國貿易促進和電子商務中心(UN/CEFACT)與結構性信息標準推進組織(OASIS)共同開發。

我們能否期望出現一個真正的面向組件(component-oriented)的語言?它的創造者會是誰呢?

Stroustrup: 我懷疑,這個領域中之所以缺乏成果,正是因為人們——主要是那些非程序員們——對“組件”這個意義含糊的字眼寄予了太多的期望。這些人士夢想,有朝一日, 組件會以某種方式把程序員趕出歷史舞臺。以后那些稱職的“設計員”只需利用預先調整好的組件,把鼠標拖一拖放一放,就把系統組合出來。對于軟件工具廠商來 說,這種想法還有另一層意義,他們認為,到時候只有他們才保留有必要的技術,有能力編寫這樣的組件。

這種想法有一個最基本的謬誤:這種組件很難獲得廣泛歡迎。一個單獨的組件或框架 (framework),如果能夠滿足一個應用程序或者一個產業領域對所提出的大部分要求的話,對于其制造者來說就是劃算的產品,而且技術上也不是很困 難。可是該產業內的幾個競爭者很快就會發現,如果所有人都采用這些組件,那么彼此之間的產品就會變得天下大同,沒什么區別,他們將淪為簡單的辦事員,主要 利潤都將鉆進那些組件/框架供應商的腰包里!

小“組件”很有用,不過產生不了預期的杠桿效應。中型的、更通用的組件非常有用,但是構造時需要非同尋常的彈性。

在C++中,我們綜合運用不同共享形式的類體系(class hierarchies),以及使用templates精心打造的接口,在這方面取得了一定的進展。我期待在這個領域取得一些有趣和有用的成果,不過我認 為這種成果很可能是一種新的C++程序設計風格,而不是一種新的語言。

Lindholm: 編寫面向組件的應用程序,好像更多的是個投資、設計和程序員管理方面的問題,而不是一個編程語言問題。當然某些語言在這方面具有先天優勢,不過如果說有什 么魔術般的新語言能夠大大簡化組件的編寫難度,那純粹是一種誤導。

微軟已經將全部賭注押在C#上,其他語言何去何從?

Stroustrup: C++在下一個十年里仍然將是一種主流語言。面對新的挑戰,它會奮起應對。一個創造了那么多出色系統的語言,絕不會“坐視落花流水春去也”。

我希望微軟認識到,它在C++(我指的是ISO標準C++)上有著巨大的利益,C++是它與IT世界內其他人之間的一座橋梁,是構造大型系統和嵌入式 系統的有效工具,也是滿足高性能需求的利器。其他語言,似乎更注重那些四平八穩的商用程序。

競爭

C#會不會獲得廣泛的接受,并且擠掉其他的語言?

Lindholm: 通常,一種語言既不會從別的語言那里獲利,也不會被擠掉。那些堅定的Fortran程序員不還用著Fortran嗎?對于個人來說,語言的選擇當然因時而 異,但就整體而言,語言的種類只會遞增,也就是說,它們之間的關系是“有你有我”而不是“有你沒我”。

對于一個新語言的接受程度,往往取決于其能力所及。Java技術被迅速接受,原因是多方面的,Internet和World Wide Web接口,在其他技術面前的挫折感,對于Java技術發展方向的全面影響能力,都是原因。另一個重要的原因是Java獨立于廠商,這意味著在兼容產品面 前可以從容選擇。

C#是否會獲得廣泛接受?視情況而定。總的來說,那些對于平臺無關性和廠商無關性漠不關心的程序員,可能會喜歡C#。那些跟微軟平臺捆在一起人當然可 能想要尋找VB 和VC的一個出色的替代品。但是對于程序跨平臺執行能力特別關注的程序員,將會堅守Java之類的語言。這種能力對于多重訪問設備(multiple access devices)和分布式計算模型至關重要,而Java語言提供了一個標準的、獨立于廠商運行時環境。

Stroustrup:C#的流行程度幾乎完全取決于微軟投入的資金多少。看上去C#的興起肯定會犧牲掉其他一些語言的利益,但是事實上未必如此。 Java的蓬勃發展并沒有給C++帶來衰敗。C++的應用仍然在穩定增長(當然,

已經不是爆炸性的增長了)。也許其他的語言也還能獲得自己的一席之地。

不過,我實在看不出有什么必要再發明一種新的專有語言。特別是微軟,既生VB,何需C#?

[編輯本段]

五、不同OOP語言各有什么優勢和劣勢?

Stroustrup: C++的優點自始至終都是這么幾條:靈活、高效,而且并非專有語言。現在ISO C++標準的出現,鞏固了最后一點。

我認為C++的高效是它最基本的優點。這種高效來自于其特有的數據和計算模型,較之Java和 C#,這種模型更加貼近機器。不過,哪些程序才真正地渴望這么高的效率?這是個問題。我認為這類程序非常多。人們對于計算機的期望,永遠都超越硬件科技的 發展速度。很顯然,Java和C#的設計者的想法不同,他們認為,在很多地方效率問題無關緊要。

C++主要的缺點,歸罪于糟糕的教育(是那些始終認為C++是個純粹面向對象語言的人,和那些把C++當成C語言變體的人導致了這種情況),歸罪于不 同平臺上的不一致性,歸罪于不完整、不標準的編譯器實現,歸罪于平臺無關的系統級程序庫的缺少。

這些問題歸于一點,就是缺乏一個卓越的廠商,能夠滿足整個C++社區的需求,勇于投入大量的資金開發必要的程序庫。

Lindholm: Java技術的成功,是因為它在合適的時間,出現在合適的地點,而且合理地選擇了語言和計算平臺的支持目標。Java并不是在所有場合都優于其他OOP語 言,但是對于出現的新問題能夠解決得很出色。它面向Internet計算環境,避免了C++中晦澀的結構,成功翻越了繼承機制的惱人問題。垃圾收集機制顯 著地提高了生產率,降低了復雜度。在網絡背景下使用虛擬機,以及有關安全性和動態加載的一系列設計選擇,迎合了正在出現的需求和愿望。這些特性使Java 不僅成為現有程序員的新武器,而且也為新的程序員創造了繁榮的市場空間。

此外,Java擁有一個標準化的、二進制形式的類庫,提供了必要的(當然并非充分的)平臺與廠商無關性。平臺與廠商無關性要求一項技術必須有清晰的規 范,摒棄那些阻礙二進制標準實施的特性。C++雖然有一個ISO標準,但其實甚至對于相同系統與相同指令體系的各個平臺,也提不出一個實用的、各版本兼容 的二進制標準。

歷史上很多使用虛擬機的語言飽受責難,是因為其不夠出色的性能問題,而這要歸過于緩慢的解釋器和糟糕的垃圾收集器。Java的早期實現也因為同樣的問 題受到嚴厲的批評。但是自那時起,業界向新的虛擬機實現技術投入了大量資金,取得了顯著的效果,如今在大部分場合,Java的性能跟常規的靜態編譯語言相 比毫不遜色。這使得程序員在獲得平臺

和廠商無關性的同時,也不必付出性能上的代價。

C++并沒有強制使用面向對象方法,因此為了編寫出色的面向對象代碼,就要求程序員們有相當強的紀律性。很多公司就是因為這個原因放棄了C++。作為 語言,Java的一個突出的優點就是強制面向對象方法,不允許非面向對象的結構。

C#介于C++和Java之間,腳踏兩只船,因此既不夠安全,又失之復雜。

對于公司來說,采用新的語言要付出巨大代價。雇不到好的程序員(沒人熟悉這種新語言),培訓費用高得驚人,學習過程中生產率和產品質量下降,多年的經 驗隨風消逝,等等。一種語言如何克服這些障礙?

Lindholm: 說得很對,采用新東西確實常常開銷巨大。不過問題是:這個新東西是否能夠節省更多的開支,或者提供巨大的改進,獲取合理的回報?很多公司發現,轉向 Java技術不論在開發的后端(盡快進入市場、快速迭代開發、維護簡單性)還是前端(跨平臺發布,適用范圍從低端設備到高端服務器的技術,安全性),都能 節省大筆的開銷。

對于新事物的接納,常常是在痛楚的壓力之下。很大程度上,這正是Java所經歷的。Java的產生,是對當時很多系統的缺陷所做出的反應。Java技 術通過下面的手段減輕了開發者的痛楚:1) 顧及了網絡計算方面的需求,是應運而生。2) 在技術能力的抉擇上,保持良好的品位,顧及了大眾的心理。3) 采用適度強制性策略推行設計決定。此外,Java技術已經成為大學教學中的主流,這同樣保證了Java開發者隊伍的不斷壯大。

但是最重要的一點是,再沒有另一種程序設計技術,能夠像Java那樣允許程序員開發基于 Internet的不同平臺之上的應用程序。Java平臺在這方面的杰出表現,已經被大量的實例證明。Java已經成為Internet上的缺省應用程序 平臺,Java APIs也成為Internet應用程序開發的天然平臺。

Stroustrup: 微軟和Sun把大筆的金錢扔在Java、VB和C#中,并不是因為他良心發現,也不是因為他們真的相信這些語言能夠帶給程序員更美好的生活,而是利益使 然。

有一個說法,認為軟件工具廠商如果能夠把應用程序開發者的專業技術任務負擔起來,將獲取巨大的經濟利益。我對其背后的經濟分析頗為懷疑,我認為這很難 成為現實,特別是當應用程序開發者使用開放的、標準化的工具時,他們可以有多種選擇,從而使上面的想法更加不可能。

多年以前,C++就已經具有泛型能力(也就是templates和STL),有運算符重載,有枚舉類型?我們會不會在Java的未來版本中看到這些特 性?Java是不是應該納入這些特性呢?

Strousturp:從1988-89年起,C++就已經有了templates。但是我們花了不少時

間來了解如何最好地運用這個工具,早期各廠家 對于template的支持在品質上也有很大的差異。有些編譯器廠商動作遲緩,至少有一個主要的編譯器廠商(好像是指微軟,微軟在Visual C++4.0才開始支持template,在此之前一直聲稱template是過于復雜而又沒什么用的技術,時至今日,Visual C++對于template的支持在主流編譯器中都屬于最差的一檔——譯者注)暗中鼓勵聲名狼藉的反template宣傳,直到他們自己終于學會了這項技 術為止。直到今天,對于template的支持在品質上仍然有待改進。

你上面提到的那些特性,我認為Java(還有C#)應該,也肯定會逐漸引入。那些對于程序員來說最有用的語言特性和概念,將會逐漸集中,成為各家主流 語言的必然之選。也就是說,我認為類似析構函數和模板特殊化之類的機制,遠遠比枚舉等機制重要得多。

Lindholm:Java技術成功的原因之一,就是很清楚哪些不該做。我們得多問幾個為什么:這項特性是不是必不可少?增加它會帶來哪些開銷?運算 符重載是C++中一項極其強大的特性,但是它也大大增加了C++語言的復雜度,很多人都難以招架。Java在各種可能的權衡之中,做出了明智的抉擇,找到 了能力與需求之間的完美平衡點。

當然,Java也會發展,而且最重要的是,現在是開發者們在推動發展。Java增加泛型能力這件事,很好地展示了Java是如何通過整個開發者社群的 參與,在權衡中決定正確的平衡點。關于增加泛型類型(generic types)的“Java規格申請”(Java Specification Request, JSR)已經進入JCP(Java Community Process)程序,而且已經開發了很長一段時間(參見 http://java.sun.com/aboutJava/communityprocess/之JSR-014)。現在,在JCP中,有超過80個 JSRs正在討論中,這充分體現了整個體系對開發者的積極反饋和高度合作,這正是驅動Java平臺不斷進化的動力。

[編輯本段]

六、發展 vs. 革新

(Evolution vs. Revolution)

C++是一種發展型的語言,Java和C#似乎更像是革新型語言(它們是從頭設計的)?什么時候,革新型的語言才是必需的呢?

Lindholm: Java技術并非憑空出世,反而更像是發展型的。Java所有的特性,在Java平臺推出之前,都至少已經存在于另一種環境之中。Java的貢獻在于,在 眾多的特性和權衡中,做出了合理的選擇,使得產品既實用,又優雅。Java技術對于程序員的態度是:撫養,但不溺愛。

Stroustrup:從技術上講,我并不認為Java和C#是什么“從頭設計的”革新型語言。倘若Java是從技術原則出發,從頭設計,大概就不會 模仿C/C++那種丑陋和病態的語法了(不必驚訝,Stroustrup在很多場合表示過,C++采用C的語法形式,實在是迫于兼容性

。他本人更偏愛 Simula的語法——譯者)。

我認為,只有當程序員們面對的問題發生了根本的變化的時候,或者當我們發現了全新的、極其優越的程序設計技術,又完全不能為現存語言所支持的時候,我 們才需要全新的語言。問題是,我們恐怕永遠也碰不到那些“根本”、“全新”的情況。

我以為,自從OOP問世以來,可稱為“根本”的新型程序設計技術,唯有泛型程序設計(generic programming)和生成式程序設計(generative programming)技術,這兩項技術主要是源于C++ templates技術的運用,也有一部分曾經被視為面向對象和函數式語言(functional languages)的次要成分,現在都變成正式、可用和可承受的技術了。我對于目前C++模板(template)程序設計的成果非常興奮。例如,像 POOMA, Blitz++和MTL等程序庫,在很多地方改變了數值計算的方式。

C#的一個“賣點”,就是它們的簡單性。現在Java是不是快失去這個賣點了?

Stroustrup:新語言總是宣稱自己如何如何簡單,對老語言的復雜性頗多非議。其實這種所謂的“簡單性”,簡單地說,就是不成熟性。語言的復雜 性,是在解決現實世界中極為煩瑣和特殊的復雜問題的過程中逐漸增加的。一個語言只要活的時間夠長,總會有某些地方逐漸復雜起來,或者是語言本身,或者是程 序庫和工具。C++和Java顯然都不例外,我看C#也一樣。如果一種語言能夠度過自己的幼年時代,它會發現,自己無論是體積還是復雜性都大大增加了。

Lindholm:Java技術的的功能在增加,需要學習的東西也在增加。不過功能的增加并不一定帶來復雜性的增加。Java技術的發展,并沒有使學 習曲線更加陡峭,只是讓它繼續向右方延展了。

標準

標準化語言和開放型語言各自的優點和缺點何在?

Lindholm:對于一個開放、不允許專有擴展、具有權威的強制性標準語言或者運行環境來說,不存在什么缺點。允許專有擴展就意味著允許廠商下套子 綁架客戶。特別重要的是,必須讓整個平臺,而不只是其中一部分完全標準化,才能杜絕廠商們利用高層次的專有API下套子。客戶要求有選擇廠商的自由,他們 既要有創造性,又需要兼容性。

Stroustrup:對于一個語言,如C/C++來說,建立正式標準(如ISO標準)最大的好處,在于可以防止某一個廠商操縱這種語言,把它當成自 己的搖錢樹。多個廠商的競爭給用戶帶來的是較低的價位和較好的穩定性。

專有語言的好處,一是流行,二是便宜(不過等你被套牢了之后,情況就會起變化),三是對于商業性需求可以做出快速的反應。

標準化語言的特點之一是,它不能忽略特殊用戶的需求。比如我在AT&T中所考慮的

東西,其規模、可靠性和效率要求,跟那些普通廠商關注的大眾 軟件相比,根本不可同日而語。那些公司很自然只關注主要的需求。

然而,多數大機構和身處前沿的公司,都有著特殊的需求。C++的設計是開放、靈活和高效的,能夠滿足我所能想象的任何需求。跟其他的現代語言相 比,C++的家長式作風可謂少之又少,原因就在這。當然,不能贊賞這一點的人會詬病C++的“危險”。

擁有正式和開放標準的語言主要是為編程工具的使用者和客戶服務的,而擁有專屬“標準”的語言,主要是為廠商服務的。

OOD

面向對象設計(Object-Oriented Design,OOD)方法是OO方法中一個中間過渡環節。其主要作用是對OOA分析的結果作進一步的規范化整理,以便能夠被OOP直接接受。

面向對象設計(OOD)是一種軟件設計方法,是一種工程化規范。這是毫無疑問的。按照Bjarne Stroustrup的說法,面向對象的編程范式(paradigm)是[Stroustrup, 97]:

l 決定你要的類;

l 給每個類提供完整的一組操作;

l 明確地使用繼承來表現共同點。

由這個定義,我們可以看出:OOD就是“根據需求決定所需的類、類的操作以及類之間關聯的過程”。

OOD的目標是管理程序內部各部分的相互依賴。為了達到這個目標,OOD要求將程序分成塊,每個塊的規模應該小到可以管理的程度,然后分別將各個塊隱 藏在接口(interface)的后面,讓它們只通過接口相互交流。比如說,如果用OOD的方法來設計一個服務器-客戶端(client-server) 應用,那么服務器和客戶端之間不應該有直接的依賴,而是應該讓服務器的接口和客戶端的接口相互依賴。

這種依賴關系的轉換使得系統的各部分具有了可復用性。還是拿上面那個例子來說,客戶端就不必依賴于特定的服務器,所以就可以復用到其他的環境下。如果 要復用某一個程序塊,只要實現必須的接口就行了。

OOD是一種解決軟件問題的設計范式(paradigm),一種抽象的范式。使用OOD這種設計范式,我們可以用對象(object)來表現問題領域 (problem domain)的實體,每個對象都有相應的狀態和行為。我們剛才說到:OOD是一種抽象的范式。抽象可以分成很多層次,從非常概括的到非常特殊的都有,而 對象可能處于任何一個抽象層次上。另外,彼此不同但又互有關聯的對象可以共同構成抽象:只要這些對象之間有相似性,就可以把它們當成同一類的對象來處理。

一、OOD背景知識

計算機硬件技術卻在飛速發展。從幾十年前神秘的龐然大物,到現在隨身攜帶的移動芯片;從每秒數千次運算到每秒上百億次運算。當軟件開發者們還在尋找能 讓軟件開發生產力提

高一個數量級的“銀彈”[Brooks, 95]時,硬件開發的生產力早已提升了百倍千倍。

硬件工程師們能夠如此高效,是因為他們都很懶惰。他們永遠恪守“不要去重新發明輪子”的古訓。Grady Booch把這些黑箱稱為類屬(class category),現在我們則通常把它們稱為“組件(component)”。

類屬是由被稱為類(class)的實體組成的,類與類之間通過關聯(relationship)結合在一起。一個類可以把大量的細節隱藏起來,只露出 一個簡單的接口,這正好符合人們喜歡抽象的心理。所以,這是一個非常偉大的概念,因為它給我們提供了封裝和復用的基礎,讓我們可以從問題的角度來看問題, 而不是從機器的角度來看問題。

軟件的復用最初是從函數庫和類庫開始的,這兩種復用形式實際上都是白箱復用。到90年代,開始有人開發并出售真正的黑箱軟件模塊:框架 (framework)和控件(control)。框架和控件往往還受平臺和語言的限制,現在軟件技術的新潮流是用SOAP作為傳輸介質的Web Service,它可以使軟件模塊脫離平臺和語言的束縛,實現更高程度的復用。但是想一想,其實Web Service也是面向對象,只不過是把類與類之間的關聯用XML來描述而已[Li, 02]。

在過去的十多年里,面向對象技術對軟件行業起到了極大的推動作用。在可以預測的將來,它仍將是軟件設計的主要技術——至少我看不到有什么技術可以取代 它的。

二、OOD到底從哪兒來?

有很多人都認為:OOD是對結構化設計(Structured Design,SD)的擴展,其實這是不對的。OOD的軟件設計觀念和SD完全不同。SD注重的是數據結構和處理數據結構的過程。而在OOD中,過程和數 據結構都被對象隱藏起來,兩者幾乎是互不相關的。不過,追根溯源,OOD和SD有著非常深的淵源。

1967年前后,OOD和SD 的概念幾乎同時誕生,它們分別以不同的方式來表現數據結構和算法。當時,圍繞著這兩個概念,很多科學家寫了大量的論文。其中,由Dijkstra和 Hoare兩人所寫的一些論文講到了“恰當的程序控制結構”這個話題,聲稱goto語句是有害的,應該用順序、循環、分支這三種控制結構來構成整個程序流 程。這些概念發展構成了結構化程序設計方法;而由Ole-Johan Dahl所寫的另一些論文則主要討論編程語言中的單位劃分,其中的一種程序單位就是類,它已經擁有了面向對象程序設計的主要特征。

這兩種概念立刻就分道揚鑣了。在結構化這邊的歷史大家都很熟悉:NATO會議采納了 Dijkstra的思想,整個軟件產業都同意goto語句的確是有害的,結構化方法、瀑布模型從70年代開始大行其道。同時,無數的科學家和軟件工程師也 幫助結構化方法不

斷發展完善,其中有很多今天足以使我們振聾發聵的名字,例如Constantine、Yourdon、DeMarco和 Dijkstra。有很長一段時間,整個世界都相信:結構化方法就是拯救軟件工業的 “銀彈”。當然,時間最后證明了一切。

而此時,面向對象則在研究和教育領域緩慢發展。結構化程序設計幾乎可以應用于任何編程語言之上,而面向對象程序設計則需要語言的支持[1],這也妨礙 了面向對象技術的發展。實際上,在60年代后期,支持面向對象特性的語言只有Simula-67 這一種。到70年代,施樂帕洛阿爾托研究中心(PARC)的 Alan Key等人又發明了另一種基于面向對象方法的語言,那就是大名鼎鼎的Smalltalk。但是,直到80年代中期,Smalltalk和另外幾種面向對象 語言仍然只停留在實驗室里。

到90年代,OOD突然就風靡了整個軟件行業,這絕對是軟件開發史上的一次革命。不過,登高才能望遠,新事物總是站在舊事物的基礎之上的。70年代和 80年代的設計方法揭示出許多有價值的概念,誰都不能也不敢忽視它們,OOD也一樣。

三、OOD和傳統方法有什么區別?

還記得結構化設計方法嗎?程序被劃分成許多個模塊,這些模塊被組織成一個樹型結構。這棵樹的根就是主模塊,葉子就是工具模塊和最低級的功能模塊。同 時,這棵樹也表示調用結構:每個模塊都調用自己的直接下級模塊,并被自己的直接上級模塊調用。

那么,哪個模塊負責收集應用程序最重要的那些策略?當然是最頂端的那些。在底下的那些模塊只管實現最小的細節,最頂端的模塊關心規模最大的問題。所 以,在這個體系結構中越靠上,概念的抽象層次就越高,也越接近問題領域;體系結構中位置越低,概念就越接近細節,與問題領域的關系就越少,而與解決方案領 域的關系就越多。

但是,由于上方的模塊需要調用下方的模塊,所以這些上方的模塊就依賴于下方的細節。換句話說,與問題領域相關的抽象要依賴于與問題領域無關的細節!這 也就是說,當實現細節發生變化時,抽象也會受到影響。而且,如果我們想復用某一個抽象的話,就必須把它依賴的細節都一起拖過去。

而在OOD中,我們希望倒轉這種依賴關系:我們創建的抽象不依賴于任何細節,而細節則高度依賴于上面的抽象。這種依賴關系的倒轉正是OOD和傳統技術 之間根本的差異,也正是OOD思想的精華所在。

四、OOD步驟

細化重組類

細化和實現類間關系,明確其可見性

增加屬性,指定屬性的類型與可見性

分配職責,定義執行每個職責的方法

對消息驅動的系統,明確消息傳遞方式

利用設計模式進行局部設計

畫出詳細的類圖與時序圖

五、OOD設計過程中要展開的主要幾項工作

(一)對象定義規格的求精過程

對于OOA所抽象出來的對象-&-類以及匯集的分析文檔,OOD需要有一個根據設計要求整理和求精的過程,使之更能符合OOP的需要。這個整理和求精 過程主要有兩個方面:一是要根據面向對象的概念

模型整理分析所確定的對象結構、屬性、方法等內容,改正錯誤的內容,刪去不必要和重復的內容等。二是進行分類整理,以便于下一步數據庫設計和程序處理 模塊設計的需要。整理的方法主要是進行歸

類,對類一&一對象、屬性、方法和結構、主題進行歸類。

(二)數據模型和數據庫設計

數據模型的設計需要確定類-&-對象屬性的內容、消息連接的方式、系統訪問、數據模型的方法等。最后每個對象實例的數據都必須落實到面向對象的庫結構 模型中。

(三)優化

OOD的優化設計過程是從另一個角度對分析結果和處理業務過程的整理歸納,優化包括對象和結構的優化、抽象、集成。

對象和結構的模塊化表示OOD提供了一種范式,這種范式支持對類和結構的模塊化。這種模塊符合一般模塊化所要求的所有特點,如信息隱蔽性好,內部聚合 度強和模塊之間耦合度弱等。

集成化使得單個構件有機地結合在一起,相互支持。

六、OO方法的特點和面臨的問題

OO方法以對象為基礎,利用特定的軟件工具直接完成從對象客體的描述到軟件結構之間的轉換。這是OO方法最主要的特點和成就。OO方法的應用解決了傳 統結構化開發方法中客觀世界描述工具與軟

件結構的不一致性問題,縮短了開發周期,解決了從分析和設計到軟件模塊結構之間多次轉換映射的繁雜過程,是一種很有發展前途的系統開發方法。

但是同原型方法一樣,OO方法需要一定的軟件基礎支持才可以應用,另外在大型的MIS開發中如果不經自頂向下的整體劃分,而是一開始就自底向上的采用 OO 方法開發系統,同樣也會造成系統結構不合理、各部分關系失調等問題。所以OO方法和結構化方法目前仍是兩種在系統開發領域相互依存的、不可替代的方法。

七、OOD能給我帶來什么?

問這個問題的人,腦子里通常是在想“OOD能解決所有的設計問題嗎?”沒有銀彈。OOD也不是解決一切設計問題、避免軟件危機、捍衛世界和平……的銀 彈。OOD只是一種技術。但是,它是一種優秀的技術,它可以很好地解決目前的大多數軟件設計問題 ——當然,這要求設計者有足夠的能力。

OOD可能會讓你頭疼,因為要學會它、掌握它是很困難的;OOD甚至會讓你失望,因為它也并不成熟、并不完美。OOD也會給你帶來欣喜,它讓你可以專 注于設計,而不必

操心那些細枝末節;OOD也會使你成為一個更好的設計師,它能提供給你很好的工具,讓你能開發出更堅固、更可維護、更可復用的軟件。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,765評論 18 399
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,284評論 25 708
  • 面向對象程序設計(英語:Object-oriented programming,縮寫:OOP)是種具有對象概念的程...
    李序鍇閱讀 1,303評論 0 5
  • 從三月份找實習到現在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發崗...
    時芥藍閱讀 42,366評論 11 349
  • 也許在這個世上我們很難找到真正屬于自己的另一個世界了吧。 從博客、微博、微信朋友圈,一路走來,你會發現屬于自己的單...
    iMe心理閱讀 208評論 0 0