面向對象
軟體開發方法
面向對象(O徠bject Oriented)是軟體開發方法。面向對象的概念和應用已超越了程序設計和軟體開發,擴展到如資料庫系統、互動式界面、應用結構、應用平台、分散式系統、網路管理結構、CAD技術、人工智慧等領域。面向對象是一種對現實世界理解和抽象的方法,是計算機編程技術發展到一定階段后的產物。
面向對象是相對於面向過程來講的,面向對象方法,把相關的數據和方法組織為一個整體來看待,從更高的層次來進行系統建模,更貼近事物的自然運行模式。
早期的計算機編程是基於面向過程的方法,例如實現算術運算1+1+2 = 4,通過設計一個演演算法就可以解決當時的問題。隨著計算機技術的不斷提高,計算機被用於解決越來越複雜的問題。一切事物皆對象,通過面向對象的方式,將現實世界的事物抽象成對象,現實世界中的關係抽象成類、繼承,幫助人們實現對現實世界的抽象與數字建模。通過面向對象的方法,更利於用人理解的方式對複雜系統進行分析、設計與編程。同時,面向對象能有效提高編程的效率,通過封裝技術,消息機制可以像搭積木的一樣快速開發出一個全新的系統。面向對象是指一種程序設計范型,同時也是一種程序開發的方法。對象指的是類的集合。它將對象作為程序的基本單元,將程序和數據封裝其中,以提高軟體的重用性、靈活性和擴展性。
面向對象的思想已經涉及到軟體開發的各個方面。如,面向對象的分析(OOA,Object Oriented Analysis),面向對象的設計(OOD,Object Oriented Design)、以及我們經常說的面向對象的編程實現(OOP,Object Oriented Programming)。
面向對象是在結構化設計方法出現很多問題的情況下應運而生的。結構化設計方法求解問題的基本策略是從功能的角度審視問題域。它將應用程序看成實現某些特定任務的功能模塊,其中子過程是實現某項具體操作的底層功能模塊。在每個功能模塊中,用數據結構描述待處理數據的組織形式,用演演算法描述具體的操作過程。面對日趨複雜的應用系統,這種開發思路在下面幾個方面逐漸暴露了一些弱點。
1.審視問題域的視角
在現實世界中存在的客體是問題域中的主角,所謂客體是指客觀存在的對象實體和主觀抽象的概念,他是人類觀察問題和解決問題的主要目標。例如,對於一個學校學生管理系統來說,無論是簡單還是複雜,始終是圍繞學生和老師這兩個客體實施。在自然界,每個客體都具有一些屬性和行為,例如學生有學號、姓名、性別等屬性,以及上課、考試、做實驗等行為。因此,每個個體都可以用屬性和行為來描述。
通常人類觀察問題的視角是這些客體,客體的屬性反應客體在某一時刻的狀態,客體的行為反映客體能從事的操作。這些操作附在客體之上並能用來設置、改變和獲取客體的狀態。任何問題域都有一系列的客體,因此解決問題的基本方式是讓這些客體之間相互驅動、相互作用,最終使每個客體按照設計者的意願改變其屬性狀態。
結構化設計方法所採用的設計思路不是將客體作為一個整體,而是將依附於客體之上的行為抽取出來,以功能為目標來設計構造應用系統。這種做法導致在進行程序設計的時候,不得不將客體所構成的現實世界映射到由功能模塊組成的解空間中,這種變換過程,不僅增加了程序設計的複雜程度,而且背離了人們觀察問題和解決問題的基本思路。另外,再仔細思考會發現,在任何一個問題域中,客體是穩定的,而行為是不穩定的。例如,不管是國家圖書館,還是學校圖書館,還是國際圖書館,都會含有圖書這個客體,但管理圖書的方法可能是截然不同的。結構化設計方法將審視問題的視角定位於不穩定的操作之上,並將描述客體的屬性和行為分開,使得應用程序的日後維護和擴展相當困難,甚至一個微小的變動,都會波及到整個系統。面對問題規模的日趨擴大、環境的日趨複雜、需求變化的日趨加快,將利用計算機解決問題的基本方法統一到人類解決問題的習慣方法之上,徹底改變軟體設計方法與人類解決問題的常規方式扭曲的現象迫在眉睫,這是提出面向對象的首要原因。
2.抽象級別
抽象是人類解決問題的基本法寶。良好的抽象策略可以控制問題的複雜程度,增強系統的通用性和可擴展性。抽象主要包括過程抽象和數據抽象。結構化設計方法應用的是過程抽象。所謂過程抽象是將問題域中具有明確功能定義的操作抽取出來,並將其作為一個實體看待。這種抽象級別對於軟體系統結構的設計顯得有些武斷,並且穩定性差,導致很難準確無誤地設計出系統的每一個操作環節。一旦某個客體屬性的表示方式發生了變化,就有可能牽扯到已有系統的很多部分。而數據抽象是較過程抽象更高級別的抽象方式,將描述客體的屬性和行為綁定在一起,實現統一的抽象,從而達到對現實世界客體的真正模擬。
3.封裝體
封裝是指將現實世界中存在的某個客體的屬性與行為綁定在一起,並放置在一個邏輯單元內。該邏輯單元負責將所描述的屬性隱藏起來,外界對客體內部屬性的所有訪問只能通過提供的用戶介面實現。這樣做既可以實現對客體屬性的保護作用,又可以提高軟體系統的可維護性。只要用戶介面不改變,任何封裝體內部的改變都不會對軟體系統的其他部分造成影響。結構化設計方法沒有做到客體的整體封裝,只是封裝了各個功能模塊,而每個功能模塊可以隨意地對沒有保護能力客體屬性實施操作,並且由於描述屬性的數據與行為被分割開來,所以一旦某個客體屬性的表達方式發生了變化,或某個行為效果發生了改變,就有可能對整個系統產生影響。
4.可重用性
可重用性標識著軟體產品的可復用能力,是衡量一個軟體產品成功與否的重要標誌。當今的軟體開發行業,人們越來越追求開發更多的、更有通用性的可重用構件,從而使軟體開發過程徹底改善,即從過去的語句級編寫發展到現在的構件組裝,從而提高軟體開發效率,推動應用領域迅速擴展。然而,結構化程序設計方法的基本單位是模塊,每個模塊只是實現特定功能的過程描述,因此,它的可重用單位只能是模塊。例如,在C語言編寫程序時使用大量的標準函數。但對於今天的軟體開發來說,這樣的重用力度顯得微不足道,而且當參與操作的某些數據類型發生變化時,就不能夠再使用那些函數了。因此,渴望更大力度的可重用構件是如今應用領域對軟體開發提出的新需求。
上述弱點驅使人們尋求一種新的程序設計方法,以適應現代社會對軟體開發的更高要求,面向對象由此產生。
對象的含義是指具體的某一個事物,即在現實生活中能夠看得見摸得著的事物。在面向對象程序設計中,對象所指的是計算機系統中的某一個成分。在面向對象程序設計中,對象包含兩個含義,其中一個是數據,另外一個是動作。對象則是數據和動作的結合體。對象不僅能夠進行操作,同時還能夠及時記錄下操作結果。
方法是指對象能夠進行的操作,方法同時還有另外一個名稱,叫做函數。方法是類中的定義函數,其具體的作用就是對對象進行描述操作。
繼承簡單地說就是一種層次模型,這種層次模型能夠被重用。層次結構的上層具有通用性,但是下層結構則具有特殊性。在繼承的過程中類則可以從最頂層的部分繼承一些方法和變數。類除了可以繼承以外同時還能夠進行修改或者添加。通過這樣的方式能夠有效提高工作效率。在這裡舉一個例子,當類X繼承了類Y后,此時的類X則是一個派生類,而類Y屬於一個基類。繼承是從一般演繹到特殊的過程,可以減少知識表示的冗餘內容,知識庫的維護和修正都非常方便。更有利於衍生複雜的系統。
類是具有相同特性(數據元素)和行為(功能)的對象的抽象。因此,對象的抽象是類,類的具體化就是對象,也可以說類的實例是對象,類實際上就是一種數據類型。類具有屬性,它是對象的狀態的抽象,用數據結構來描述類的屬性。類具有操作,它是對象的行為的抽象,用操作名和實現該操作的方法來描述。類映射的每一個對象都具有這些數據和操作方法,類的繼承具有層次性和結構性,高層次對象封裝複雜行為,具體細節對該層次知識保持透明,可以減小問題求解的複雜度。
封裝是將數據和代碼捆綁到一起,對象的某些數據和代碼可以是私有的,不能被外界訪問,以此實現對數據和代碼不同級別的訪問許可權。防止了程序相互依賴性而帶來的變動影響,面向對象的封裝比傳統語言的封裝更為清晰、更為有力。有效實現了兩個目標:對數據和行為的包裝和信息隱藏。
多態是指不同事物具有不同表現形式的能力。多態機制使具有不同內部結構的對象可以共享相同的外部介面,通過這種方式減少代碼的複雜度。一個介面,多種方式。
動態綁定指的是將一個過程調用與相應代碼鏈接起來的行為。動態綁定是指與給定的過程調用相關聯的代碼只有在運行期才可知的一種綁定,它是多態實現的具體形式。
消息傳遞:對象之間需要相互溝通,溝通的途徑就是對象之間收發信息。消息內容包括接收消息的對象的標識,需要調用的函數的標識,以及必要的信息。消息傳遞的概念使得對現實世界的描述更容易。
面向對象的方法就是利用抽象、封裝等機制,藉助於對象、類、繼承、消息傳遞等概念進行軟體系統構造的軟體開發方法。
(1)對象唯一性。
每個對象都有自身唯一的標識,通過這種標識,可找到相應的對象。在對象的整個生命期中,它的標識都不改變,不同的對象不能有相同的標識。
(2)抽象性。
抽象性是指將具有一致的數據結構(屬性)和行為(操作)的對象抽象成類。一個類就是這樣一種抽象,它反映了與應用有關的重要性質,而忽略其他一些無關內容。任何類的劃分都是主觀的,但必須與具體的應用有關。
(3)繼承性。
繼承性是子類自動共享父類數據結構和方法的機制,這是類之間的一種關係。在定義和實現一個類的時候,可以在一個已經存在的類的基礎之上來進行,把這個已經存在的類所定義的內容作為自己的內容,並加入若干新的內容。
繼承性是面向對象程序設計語言不同於其它語言的最重要的特點,是其他語言所沒有的。
在類層次中,子類只繼承一個父類的數據結構和方法,則稱為單重繼承。
在類層次中,子類繼承了多個父類的數據結構和方法,則稱為多重繼承。
多重繼承,JAVA、VB、NET、Objective-C均僅支持單繼承,注意在C++多重繼承時,需小心二義性。
在軟體開發中,類的繼承性使所建立的軟體具有開放性、可擴充性,這是信息組織與分類的行之有效的方法,它簡化了對象、類的創建工作量,增加了代碼的可重用性。
採用繼承性,提供了類的規範的等級結構。通過類的繼承關係,使公共的特性能夠共享,提高了軟體的重用性。
(4)多態性(多形性)
多態性是指相同的操作或函數、過程可作用於多種類型的對象上並獲得不同的結果。不同的對象,收到同一消息可以產生不同的結果,這種現象稱為多態性。
多態性允許每個對象以適合自身的方式去響應共同的消息。
多態性增強了軟體的靈活性和重用性。
面向對象開發方法的研究已日趨成熟,國際上已有不少面向對象產品出現。面向對象開發方法有Coad方法、Booch方法和OMT方法等。
1、Booch方法
Booch最先描述了面向對象的軟體開發方法的基礎問題,指出面向對象開發是一種根本不同於傳統的功能分解的設計方法。面向對象的軟體分解更接近人對客觀事務的理解,而功能分解只通過問題空間的轉換來獲得。
2、Coad方法
Coad方法是1989年Coad和Yourdon提出的面向對象開發方法。該方法的主要優點是通過多年來大系統開發的經驗與面向對象概念的有機結合,在對象、結構、屬性和操作的認定方面,提出了一套系統的原則。該方法完成了從需求角度進一步進行類和類層次結構的認定。儘管Coad方法沒有引入類和類層次結構的術語,但事實上已經在分類結構、屬性、操作、消息關聯等概念中體現了類和類層次結構的特徵。
3、OMT方法
OMT方法是1991年由James Rumbaugh等5人提出來的,其經典著作為“面向對象的建模與設計”。
該方法是一種新興的面向對象的開發方法,開發工作的基礎是對真實世界的對象建模,然後圍繞這些對象使用分析模型來進行獨立於語言的設計,面向對象的建模和設計促進了對需求的理解,有利於開發得更清晰、更容易維護的軟體系統。該方法為大多數應用領域的軟體開發提供了一種實際的、高效的保證,努力尋求一種問題求解的實際方法。
4、UML(Unified Modeling Language)語言
軟體工程領域在1995年~1997年取得了前所未有的進展,其成果超過軟體工程領域過去15年的成就總和,其中最重要的成果之一就是統一建模語言(UML)的出現。UML將是面向對象技術領域內佔主導地位的標準建模語言。
UML不僅統一了Booch方法、OMT方法、OOSE方法的表示方法,而且對其作了進一步的發展,最終統一為大眾接受的標準建模語言。UML是一種定義良好、易於表達、功能強大且普遍適用的建模語言。它融入了軟體工程領域的新思想、新方法和新技術。它的作用域不限於支持面向對象的分析與設計,還支持從需求分析開始的軟體開發全過程。
面向對象編程(Object Oriented Programming,OOP,面向對象程序設計)的主要思想是把構成問題的各個事務分解成各個對象,建立對象的目的不是為了完成一個步驟,而是為了描敘一個事物在整個解決問題的步驟中的行為。面向對象程序設計中的概念主要包括:對象、類、數據抽象、繼承、動態綁定、數據封裝、多態性、消息傳遞。通過這些概念面向對象的思想得到了具體的體現。
傳統的結構化設計方法的基本點是面向過程,系統被分解成若干個過程。而面向對象的方法是採用構造模型的觀點,在系統的開發過程中,各個步驟的共同的目標是建造一個問題域的模型。在面向對象的設計中,初始元素是對象,然後將具有共同特徵的對象歸納成類,組織類之間的等級關係,構造類庫。在應用時,在類庫中選擇相應的類。
面對對象程序設計是儘可能地在模擬人類的思維。通過這樣的方式能夠讓開發的軟體更加符合人類的認知,人們使用起來也能夠更加順手。並且通過應用軟體能夠切實地解決現實生活中的問題。面向對象程序設計使得描述問題的問題空間和問題的解決方法空間組合在一起,並且儘可能地保持一致。能夠將客觀世界中的抽象問題轉化為具體的問題對象。
面向對象的思維更符合人認識和思考問題的方式,面向對象的概念和應用已經超越了軟體開發和程序設計,擴展到多個的領域,其中一個應用的分支就是面向對象的知識表示法。這種表示法把組成客觀世界的實體抽象為數據和對數據的操作,並使用類把數據和對數據的操作封裝成為一個不可分割、互相依存的整體。面向對象表示的知識更接近客觀世界,表示方案更加自然,易於理解。面向對象技術良好的模塊性,面向對象的系統良好的可維護性、可擴充性和可重用性等特點,正符合人們組織和管理知識庫的需求。
(一)程序設計語言
⒈選擇面向對象語言
採用面向對象方法開發軟體的基本目的和主要優點是通過重用提高軟體的生產率。因此,應該優先選用能夠最完善、最準確地表達問題域語義的面向對象語言。
在選擇編程語言時,應該考慮的其他因素還有:對用戶學習面向對象分析、設計和編碼技術所能提供的培訓操作;在使用這個面向對象語言期間能提供的技術支持;能提供給開發人員使用的開發工具、開發平台,對機器性能和內存的需求,集成已有軟體的容易程度。
⒉程序設計風格
⑴提高重用性。
⑵提高可擴充性。
⑶提高健壯性。
(二)類的實現
在開發過程中,類的實現是核心問題。在用面向對象風格所寫的系統中,所有的數據都被封裝在類的實例中。而整個程序則被封裝在一個更高級的類中。在使用既存部件的面向對象系統中,可以只花費少量時間和工作量來實現軟體。只要增加類的實例,開發少量的新類和實現各個對象之間互相通信的操作,就能建立需要的軟體。
一種方案是先開發一個比較小、比較簡單的來,作為開發比較大、比較複雜的類的基礎。
⑴“原封不動”重用。
⑵進化性重用。
一個能夠完全符合要求特性的類可能並不存在。
⑶“廢棄性”開發。
不用任何重用來開發一個新類。
⑷錯誤處理。
一個類應是自主的,有責任定位和報告錯誤。
(三)應用系統的實現
應用系統的實現是在所有的類都被實現之後的事。實現一個系統是一個比用過程性方法更簡單、更簡短的過程。有些實例將在其他類的初始化過程中使用。而其餘的則必須用某種主過程顯式地加以說明,或者當作系統最高層的類的表示的一部分。
在C++和C中有一個main()函數,可以使用這個過程來說明構成系統主要對象的那些類的實例。
(四)面向對象測試
⑴演演算法層。
⑵類層。
測試封裝在同一個類中的所有方法和屬性之間的相互作用。
⑶模板層。
測試一組協同工作的類之間的相互作用。
⑷系統層。
把各個子系統組裝成完整的面向對象軟體系統,在組裝過程中同時進行測試。
面向對象方法的提取類似決策樹的構思,從簡到繁,先剔除其他無關信息,再經過多次篩選找出有用的地物類別,實現地物的分層提取。經過多尺度分割后,需要對分割后的單個對象進行劃分,選擇合適的參數或者規則將對象與其他對象區分開來,以實現各種地物的分類。
面向對象分類提取信息的方法較傳統分類方法更具有優勢,前者充分考慮高解析度影像的各種類型的特徵,包括光譜、形狀和紋理等空間特徵。而後者是通過選擇訓練樣本,軟體自動建立判別函數對其他未識別的樣本進行判斷。相比而言,面向對象方法在這方面更具有針對性,目標更明確,針對的就是分割后的圖斑,因此分類的結果精度更高。但如何應用好面向對象的方法,需要研究者掌握其相關的軟體操作和機理,比如分割尺度的設定、特徵空間的選擇。
使用面向對象分類的過程中,易受人的主觀因素影響。比如特徵空間的構建、特徵體系的建立,在分類的后處理中也同樣涉及了人機交互修正。因此,面向對象的方法雖然智能,但如果能盡量減少人工的參與,可能會提升該方法的智能化水平。
面向對象的三大特點(封裝,繼承,多態)缺一不可。通常“基於對象”是使用對象,但是無法利用現有的對象模板產生新的對象類型,繼而產生新的對象,也就是說“基於對象”沒有繼承的特點。而“多態”表示為父類類型的子類對象實例,沒有了繼承的概念也就無從談論“多態”。很多流行技術都是基於對象的,它們使用一些封裝好的對象,調用對象的方法,設置對象的屬性。但是它們無法讓程序員派生新對象類型。他們只能使用現有對象的方法和屬性。所以當你判斷一個新的技術是否是面向對象的時候,通常可以使用后兩個特性來加以判斷。“面向對象”和“基於對象”都實現了“封裝”的概念,但是面向對象實現了“繼承和多態”,而“基於對象”沒有實現這些,的確很饒口。
面向過程就是分析出解決問題所需要的步驟,然後用函數把這些步驟一步一步實現,使用的時候一個一個依次調用就可以了;面向對象是把構成問題事務分解成各個對象,建立對象的目的不是為了完成一個步驟,而是為了描敘某個事物在整個解決問題的步驟中的行為。
可以拿生活中的實例來理解面向過程與面向對象,例如五子棋,面向過程的設計思路就是首先分析問題的步驟:1、開始遊戲,2、黑子先走,3、繪製畫面,4、判斷輸贏,5、輪到白子,6、繪製畫面,7、判斷輸贏,8、返回步驟2,9、輸出最後結果。把上面每個步驟用不同的方法來實現。
如果是面向對象的設計思想來解決問題。面向對象的設計則是從另外的思路來解決問題。整個五子棋可以分為1、黑白雙方,這兩方的行為是一模一樣的,2、棋盤系統,負責繪製畫面,3、規則系統,負責判定諸如犯規、輸贏等。第一類對象(玩家對象)負責接受用戶輸入,並告知第二類對象(棋盤對象)棋子布局的變化,棋盤對象接收到了棋子的變化就要負責在屏幕上面顯示出這種變化,同時利用第三類對象(規則系統)來對棋局進行判定。
可以明顯地看出,面向對象是以功能來劃分問題,而不是步驟。同樣是繪製棋局,這樣的行為在面向過程的設計中分散在了多個步驟中,很可能出現不同的繪製版本,因為通常設計人員會考慮到實際情況進行各種各樣的簡化。而面向對象的設計中,繪圖只可能在棋盤對象中出現,從而保證了繪圖的統一。