面向對象剖析
#### 1. 面向對象
##### 1.1 為什麼有面向對象呢?
在軟體開發的歷史進程中,面向對象並非一開始就有,而在70年代才出現的,那麼為什麼會產生面向對象呢,換言之非面向對象編程遇到了什麼的問題呢。以面向過程為例,自頂向下的設計思想被論證是成功的,面向過程將解決問題劃分成step by step,類似於工廠流水線一下,第一道環節做么,下一道環節做什麼,提前就規劃得非常好。工廠流水線,是相對固定的,一條流水線也得用上幾年,如果頻繁修改,那工廠還用不用生產了呢?這樣可以推出這樣的一個道理:面向過程適用於穩定的業務場景,不利於頻繁變化的業務場景。然而,軟體開發中,變化是常態,所以可以得出一個結論:面向對象的出現是為了解決可擴展性問題。
##### 1.2 何為面向對象呢?
在面向過程中,用了類比:面向過程 = 流水線,那面向對象呢?我們經常聽到這樣的一句話,面向對象是按照人的思維去思考問題。有一個問題馬上就出來了,什麼是人的思維去思考問題呢?可惜大部分書籍並沒有提到,作者以為大家都懂。這句話很有意思,究竟人的思維是什麼,之前在讀書的時候學習人工智慧的課程,學習了一些演算法,會發現,人工智慧中的機器學習,有很多聚類、分類的演算法,機器學習也是將人的學習思維賦於給機器,使之更強大。到這裡了,隱約可以看到人的思維思考問題有分類的思想在裡面,不知不覺中會去分類、去總結歸納,把一些具有共性的物歸納在一起。譬如:在設計模式中,把常用的設計模式劃分為 創建型、結構型、形為型,這就是一個分類,把具有相似特徵的設計模式歸納為一類。
分類在一起的物具有共同的特徵,有共性,也有個性,這些物有時還會有機組成在一起、相互關聯、相互協作處理,這裡具體的物稱之對象。到這裡,可以推出一個結論:面向對象 = 對象 + 協作。
##### 1.3 面向對象特性推導
在學習面向對象時,經常講到面向對象三大特性:封裝、繼承、多態。當然這是沒有錯的,只是一開始給我們正面的結論,那不僅要發問了,為什麼面向對象的三大特性是它們,又是如何得出這個結論的呢,下面從因果關係來推導。
###### 1.3.1 封裝
在講封裝之前,還有一個概念是"抽象",抽象本身就是一個抽象的概念,按照中文的拆字分析來看,它有兩部分:抽和象,這兩個字一折,意思就出來了:抽取出來的東西像原來的東西。問題又來了,到底要抽取什麼呢?站在不同的業務角度去看問題的關注點,比如:人,如果是學生,關注的是姓名、學號、班級、成績......,如果是戶籍,關注的是姓名、年齡、住址、家庭結構.......,如果是醫院,關注的是姓名、年齡、血型、身高、體重、病史.......,所以這個概念現在比較好理解了,就是抽取我們需要關注的點,並且能反映對象本身的特性。
上面講的抽象,只是從屬性角度去思考,還有行為能力、對象關聯關係,其中對象的關聯關係放到下一小點去分析。抽象的產出是為封裝服務的,封裝的目的有兩個:屏蔽和隔離。
所以到這裡,總結一下,我們看待問題,會站在思考的角度去關注業務點,把這些業務點抽取出來形式對象,並且這些對象能反映出事物的特性,因此,封裝是第一步,它是對象產出的源泉。
###### 1.3.2 繼承
還記得上面面向對象的公式么?面向對象 = 對象 + 協作,有協作就會有關聯關係,上面也講到,對象之間有關聯關係,關聯關係有:繼承、關聯、聚合、組合。關聯關係其實可以歸納成兩類:縱向和橫向,縱向是有層次結構的,橫向是水平結構的,其中繼承就是縱向結構的。繼承的出現是為了解決重複性的問題,其實它並不是面向對象的天然特性,在實踐的過程,我們不知不覺把具有相同的東西下沉,形成公共方法,繼承就是把共同的方法上升為父類,並且子類又可以有自己的獨特的特性。
###### 1.3.3 多態
面向對象的出現是為了可擴展性,那怎麼做到可擴展性呢?可擴展性表示的是一種可能性,代表了無限可能性。從這個角度,可以推導出:可擴展性是不依賴於具體,而是依賴一種可能變化的東西。那又怎麼表示可變化的東西呢?最簡單的就是變數,即然是變數,就是隨時可以變化的,變數僅僅是一個佔位符,它不依賴於具體,而是代表同一類事物下的無限可能性。從變數的思想中,又可以得出這麼一個結論:凡是有變化的地方,只要給一個佔位表示就行,至於這個點位表示的具體是什麼,並不關心。最簡單的變數是基本數據類型,後面隨著業務的複雜些,基本數據類型無法表示無限可能性,面向對象提出了"介面"的概念,只要按照約定就行,而不關心具體的實現。我們經常也聽到,面向介面編程,依賴於抽象、不依賴於具體的實現,就是這個道理。
#### 2. 總結
這篇文章從另外一個角度去剖析了面向對象,面向對象的產生是為了解決軟體的可擴展性問題。怎麼去解決這個可擴展性問題,從個問題出發,探討了封裝、繼承、多態,知道這三個概念是怎麼來的,並不是被動的接收結論。也在準備下一篇文章 "設計模式剖析",也將沿續本文的風格,一步一步去探討什麼是設計模式、設計模式的本質是什麼、如何去推導常見的設計模式,設計模式的基礎是面向對象,所以先講了什麼是面向對象。
推薦閱讀: