對象導(dǎo)論
time: 2018-06-30 09:36:50
我們之所以將自然界分解,組織成各種概念,并按其含義分類,主要是因為我們是整個口語交流社會共同遵守的協(xié)定的參與者厢洞,這個協(xié)定以語言的形式固定下來……除非贊成這個協(xié)定中規(guī)定的有關(guān)語言信息的組織和分類,否則我們根本無法交談躺翻。
—— Benjamin Lee Whorf (1987~1941)
計算機革命起源于機器丧叽,因此,編程語言的產(chǎn)生也始于對機器的模仿公你。
1. 抽象過程
所有編程語言都提供抽象機制蠢正。可以認為省店,人們所能夠解決的問題的復(fù)雜性直接取決于抽象的類型和質(zhì)量。所謂的 “類型” 是指 “所抽象的是什么笨触?”懦傍。
程序員必須建立起在機器模型(位于 “解空間” 內(nèi),這是你對問題建模的地方芦劣,例如計算機)和實際待解問題的模型(位于 “問題空間” 內(nèi)粗俱,這是問題存在的地方,例如一項業(yè)務(wù))之間的聯(lián)系虚吟。建立這種映射是費力的寸认,而且這不屬于編程語言所固有的功能,這使得程序難以編寫串慰,并且維護代價高昂偏塞,同時也產(chǎn)生了作為副產(chǎn)物的 “編程方法” 行業(yè)。
面向?qū)ο蠓绞酵ㄟ^向程序員提供表示問題空間中的元素的工具而更進了一步邦鲫。這種表示方式非常通用灸叼,使得程序員不會受限于任何特定類型的問題。我們將問題空間中的元素及其在解空間中的表示稱為 “對象”庆捺。(你還需要一些無法類比為空間問題元素的對象古今。)這種思想的實質(zhì)是:程序可以通過添加新類型的對象使自身適用于某個特定問題。因此滔以,當(dāng)你在閱讀描述解決方案的代碼時捉腥,也是在閱讀問題的表述。相比以前我們所使用的語言你画,這是一種更靈活和更強有力的語言抽象抵碟。所以, OOP 允許根據(jù)問題來描述問題撬即,而不是根據(jù)運行解決方案的計算機來描述問題立磁。但是它任然與計算機有聯(lián)系: 每個對象看起來都有點像一臺微型計算機——它具有狀態(tài),還具有操作剥槐,用戶可以要求對象執(zhí)行這些操作唱歧。如果要對現(xiàn)實世界中的對象做類比,那么說它具有特性和行為似乎不錯。
Alan Kay 曾經(jīng)總結(jié)了第一個成功的面向?qū)ο笳Z言的五個基本特性颅崩,這些特性表現(xiàn)了一種純粹的面向?qū)ο蟪绦蛟O(shè)計方式:
- 萬物皆為對象
將對象視為奇特的變量几于,它可以存儲數(shù)據(jù),除此之外沿后,你還可以要求它在自身上執(zhí)行操作沿彭。理論上講,你可以抽取待解決問題的任何概念化構(gòu)建(狗尖滚,建筑物喉刘、服務(wù)等),將其表示為程序中的對象
- 程序是對象的集合漆弄,它們通過發(fā)送消息來告知彼此所需要做的睦裳。
想要請求一個對象,就必須對該對象發(fā)送一條消息撼唾。更具體地說廉邑,可以把消息想象為對某個特定對象的方法的調(diào)用請求。
- 每個對象都有自己的由其他對象所構(gòu)成的存儲倒谷。
換句話說蛛蒙,可以通過創(chuàng)建包含現(xiàn)有對象的包的方式來創(chuàng)建新類型的對象。因此渤愁,可以在程序中構(gòu)建復(fù)雜的體系牵祟,同時將其復(fù)雜性隱藏在對象的簡單性背后。
- 每個對象都有其類型猴伶。
按照通用的說法课舍,“每個對象都是其某各類(class)的一個實例(instance)”,這里 “類” 就是 “類型” 的同義詞他挎。每個類最重要的區(qū)別于其他類的特性就是“可以發(fā)送什么樣的消息給它”筝尾。
- 某一特定類型的所有對象都可以接受同樣的消息。
這是一句以為深長的表述办桨,你在稍后便會看到筹淫。因為 “圓形” 類型的對象同時也是 “幾何形” 類型的對象,所以一個 “圓形” 對象必定能夠接受發(fā)送給 “幾何形” 對象的消息呢撞。這意味著可以編寫與 “幾何形” 交互并自動處理所有與幾何性質(zhì)相關(guān)的事務(wù)的代碼损姜。這種可替代性(substitutability)是 OOP 中最強有力的概念之一。
Booch 對對象提出了一個更加簡潔的描述:對象具有狀態(tài)殊霞、行為和標識摧阅。這意味著每一個對象都可以擁有內(nèi)部數(shù)據(jù)(它們給出了該對象的狀態(tài))和方法(它們的行為),并且每一個對象都可以唯一地與其他對象區(qū)分開來绷蹲,具體來說棒卷,就是每一個對象在內(nèi)存中都有一個唯一的地址顾孽。
2. 每個對象都有一個接口
在面向?qū)ο蟪绦蛟O(shè)計中實際上進行的是創(chuàng)建新的數(shù)據(jù)類型,但事實上所有的面向?qū)ο蟪绦蛟O(shè)計語言都使用了 class 這個關(guān)鍵字來表示數(shù)據(jù)類型比规。
類描述了具有相同特性(數(shù)據(jù)元素)和行為(功能)的對象集合若厚,一個類實際上就是一個數(shù)據(jù)類型。程序員通過定義類來適應(yīng)問題蜒什,而不再被迫只能使用現(xiàn)有的用來表示機器中的存儲單元的數(shù)據(jù)類型测秸。可以根據(jù)需求灾常,通過添加新的數(shù)據(jù)類型來擴展編程語言霎冯。編程系統(tǒng)欣然接受新的類,并且像對待內(nèi)置類型一樣地照管它們和進行類型檢查钞瀑。
面向?qū)ο蠓椒ú⒉皇莾H局限于構(gòu)建仿真程序肃晚。無論你是否贊成一下觀點,即任何程序都是你所設(shè)計的系統(tǒng)的一種仿真仔戈,面向?qū)ο蠹夹g(shù)的應(yīng)用確實可以將大量的問題容易地降解為一個簡單地解決方案。
接口確定了對某一特定對象所能發(fā)出的請求拧廊。但是监徘,在程序中必須有滿足這些請求的代碼。這些代碼與隱藏數(shù)據(jù)一起構(gòu)成了實現(xiàn)吧碾。從過程編程的觀點來看凰盔,這并不太復(fù)雜。在類型中倦春,每一個可能的請求都有一個方法與之相關(guān)聯(lián)户敬,當(dāng)向?qū)ο蟀l(fā)送請求時,與之相關(guān)聯(lián)的方法就會被調(diào)用睁本。
3. 每個對象都提供服務(wù)
當(dāng)正在試圖開發(fā)或理解一個程序設(shè)計時尿庐,最好的方法之一就是將對象想象為 “服務(wù)提供者”。程序本身將向用戶提供服務(wù)呢堰,它將通過調(diào)用其他對象提供服務(wù)來實現(xiàn)這一目的抄瑟。你的目標就是去創(chuàng)建(或者最好是在現(xiàn)有代碼庫中尋找)能夠提供理想的服務(wù)來解決問題的一系列對象。
將對象看作服務(wù)提供者還有另外一個附帶的好處:它有助于提高對象的內(nèi)聚性枉疼。高內(nèi)聚是軟件設(shè)計的基本質(zhì)量要求之一:這意味著一個軟件構(gòu)件(例如一個對象皮假,當(dāng)然他也有可能是指一個方法或一個庫)的各個方面 “組合” 得很好。人們在設(shè)計對象時所面臨的一個問題是骂维,將過多的功能都塞在一個對象中惹资。
在良好的面向?qū)ο笤O(shè)計中,每個對象都可以很好地完成一項任務(wù)航闺,但是它并不試圖做更多的事褪测。
將對象作為服務(wù)提供者看待是一件偉大的簡化工具,這不僅在設(shè)計過程中非常有用,而且當(dāng)其他人試圖理解你的代碼或重用某個對象時汰扭,如果他們看出了這個對象所能提供的服務(wù)的價值稠肘,它會使調(diào)整對象以適應(yīng)其設(shè)計的過程變得簡單得多。
4. 被隱藏的具體實現(xiàn)
將程序開發(fā)人員按照角色分為類創(chuàng)建者(那些創(chuàng)建新數(shù)據(jù)類型的程序員)和客戶端程序員(那些在其應(yīng)用中使用數(shù)據(jù)類型的消費者)是大有裨益的萝毛∠钜酰客戶端程序員的目標是收集各種用來實現(xiàn)快速應(yīng)用開發(fā)的類。類創(chuàng)建者的目標是構(gòu)建類笆包,這種類只向客戶端程序員暴露必須的部分环揽,而隱藏其他部分。
訪問控制的原因:
- 讓客戶端程序員無法觸及他們不應(yīng)該觸及的部分——這些部分對數(shù)據(jù)類型的內(nèi)部操作來說是必需的庵佣,但并不是客戶解決特定問題所需的接口的一部分歉胶。這對客戶端程序員來說其實是一項服務(wù),因為他們可以很容易地看出那些東西對他們來說很重要巴粪,而哪些東西可以忽略通今。
- 允許庫設(shè)計者可以改變類內(nèi)部的工作方式而不用擔(dān)心會影響到客戶端程序員。如果接口和實現(xiàn)可以清晰地分離并得以保護肛根,那么你就可以輕而易舉地完成這項工作辫塌。
1.5 復(fù)用的具體實現(xiàn)
一旦類被創(chuàng)建并被測試完,那么它就應(yīng)該(在理想情況下)代表一個有用的代碼單元派哲。事實證明臼氨,這種復(fù)用性并不容易達到我們所希望的哪種程度,產(chǎn)生一個可復(fù)用的對象設(shè)計需要豐富的經(jīng)驗和敏銳的洞察力芭届。但是一旦你有了這樣的設(shè)計储矩,它就可供復(fù)用。代碼復(fù)用是面向?qū)ο蟪绦蛟O(shè)計語言所提供的最了不起的優(yōu)點之一褂乍。
最簡單地復(fù)用某個類的方式就是直接使用該類的一個對象持隧,此外也可以將那個類的一個對象置于某個新的類中。
使用現(xiàn)有的類合成新的類逃片,所以這種概念被稱為組合(composition)舆蝴,如果組合是動態(tài)發(fā)生的,那么它通常被稱為聚合(aggregation)题诵。組合經(jīng)常被視為 “has-a” (擁有)關(guān)系洁仗。
組合帶來了極大的靈活性。新類的成員對象通常都被聲明為 private性锭,使得使用新類的客戶端程序員不能訪問它們赠潦。這也使得你可以在不干擾現(xiàn)有客戶端代碼的情況下,修改這些成員草冈。也可以在運行時修改這些成員對象她奥,以實現(xiàn)動態(tài)修改程序的行為瓮增。繼承不具有這樣的靈活性。
1.6 繼承
P39