關於面向對象的深入理解

關於面向對象的深入理解

引言

第一次接觸面向對象是在大一下學期的Java程序語言設計這門課上,聽了老師講了各種名詞:類、對象、接口、繼承、多態、封裝……。當時也是一知半解,只是知道有這些東西,用的時候也是依葫蘆畫瓢,並不能理解其真正的設計內涵。隨着項目經驗的增加,也逐步體會出些許程序設計的精妙所在,再加之讀各類書籍有所心得,故準備寫這一些列文章,分享交流。

如果把程序員比作劍客的話,那麼有兩件東西最爲重要:寶劍與劍術。寶劍可以理解爲各種實打實的硬技能,比如:Java、MySQL、SpringBoot……,這些東西是死的,知識點很明確,及時與別人有所差距,下點功夫總能趕得上;而劍術則是程序設計之道,比如:需求分析、架構設計,這些東西相對來回活泛了許多,因爲在這個過程中你所面對的不再是熱騰騰的機器,而是各種各樣的客戶、複雜的業務邏輯和想法各異的同事們。所以,碼農與程序員的差別就在於程序設計方面。設計本身就是一門藝術,那些統領千萬代碼大軍的CTO們,是運籌帷幄的將軍也是才華橫溢的藝術家啊!

從面向機器到面向對象

最開始的計算機程序編碼就是0101,完全要以機器的二進制思維去思考問題;後來有了彙編只是編碼形式上有了變化,但是本質並沒有改變,程序員們的關注點還是在於機器本身,程序員要對CPU、寄存器等硬件瞭如指掌;當C語言、COBOL等面向過程的語言橫空出世後,這是一次本質上的革命,把程序員從二進制的世界中解救了出來,終於可以讓他們“像人一樣”去思考問題啦。

此時程序員可以專注於問題本身,理清解決問題的具體步驟,然後將之用程序語言講給計算機就可以啦。對於單一、具體的問題無論其複雜與否,採用面向過程的語言都可以完全hold住。這就如同流水線作業一般,環環相扣,問題複雜了無非就是工序多一些而已,整體來看難度不大。但是隨着計算機硬件的發展,人們希望用計算機處理的事務也越來越多,業務邏輯也越來越複雜,此時再用面向過程的語言去實現如此紛亂的業務邏輯就有些難以招架了。就如同好多條生產流水線摻雜在了一起,A線依賴B線上的一道工序,B線又依賴於C線的一道工序,而C線還和A線有着關聯;這樣雜亂的流水線普通主管看了肯定會頭大。此時就需要面向對象的程序設計語言來大殺四方了。

面向對象這種設計思想更加適合對於現實世界的模擬,更加適合處理一個系統性問題。它不再是以具體的點爲中心,而是着眼於整個面。用類抽象出一羣事物的共性,用接口定義好不同事物之間的交流規則,用繼承的方式讓同一類的事物也可以千姿百態,用多態的方式讓千姿百態的事物也可以整齊劃一。每個程序員都是代碼世界的上帝,以面向對象的思想去設計整個世界的架構,以面向過程的思想去研究世界的每一株土木,方可達到一花一世界,一葉一菩提的境界。

面向對象三劍客

物以類聚,人以羣分。——《戰國策·齊策三》

類是整個面向對象設計理論的基石,只有把類搞清楚搞明白了才能讓整個理論大廈有堅實的地基。

首先拋開程序設計,單從現實世界的角度來看:槍保衛祖國的人叫軍人,在工地上幹活的人叫工人,在高級寫字樓裏面辦公的人叫白領。對於每一類人,他們每個個體都不相同,但是它們都有相似的特徵,所以我們把他們歸爲的一類人。面向對象最根本的思想就是對於現實世界的模擬,用程序語言來表述業務邏輯。所以程序中的類可以這樣理解:類是一組相似事物的統稱,是對他們共性的一種歸納。 類具有屬性和方法,從軍人的角度來看他們所屬於的部隊、所駐守的地區……,這是軍人的屬性;他們可射擊、可擒拿……這是他們的方法。

實際上世間萬物皆可歸於一類,因爲只要有相似點,就有依據把他們歸於一類。那應該如何來設計類呢?請記住這樣一句話:橫看成嶺側成峯,遠近高低各不同。角度決定看法,一定要結合具體需求,來考慮類的設計。

類有屬性和方法,那麼如何劃分屬性和方法呢?這裏應該遵循極簡原則。即屬性原子化、方法單一化。屬性細化到不能再分割,方法只能做一件事。這樣能夠最大化地解耦,滿足系統的可拓展性與易修改性。

對象

對於類的認知清晰以後,對象就比較容易理解了。
對象就是類的一個具體實例。以軍人爲例,黃繼光,邱少雲就是軍人這一類人當中一個具體的實例。

其實關於類和對象還可以深入探究一下,爲什麼有了類還會有對象?類和對象各自的作用是什麼?這個時候我們還是要回歸於現實世界。中國的人很多,那麼黨和政府如何來組織管理我們呢?首先不同的人有不同的職業,比如醫生、教師、軍人、工人等等。政府依據不同類別的職業制定出了不同的政策,比如軍人買票優先、教師遊覽一些景點免費。其實依據不同職業有不同治理策略是一種歸類更是一種抽象。

抽象的本質就是隔離干擾、總結共性、降低事物的複雜度,站在更高的角度去看待問題,從而更好地把控全局。所以類對於程序員來說是一種抽象的工具,讓我們能夠更好地全局把控整個項目,組織管理整個項目。黨和國家領導人提出了全面建設小康社會,提出社會主義核心價值觀等理論,有些普通民衆看起來是空話套話,原因他們的視野只侷限於自己的一畝三分地,看到的是具體的事務,而習大大則是心繫整個國家,他說的話是立足於整個中國,對於億萬華夏兒女都有用的話。所以習大大是對中國國情高度總結歸納抽象後才能提出這樣的理論!

對於程序員來說,類是抽象的,對象是具體的,擁有了類就擁有了上帝視角,來俯瞰整個系統;擁有了對象就擁有的億萬子民,來進行勞動,創造價值。

類.png

接口

“接口”這個詞是被濫用、亂用最多的術語了。拋開其他的接口不談,這裏主要是說一下面向對象中的接口。如果只看教科書上的定義,你很容易明白接口具體是什麼:

Java接口是一系列方法的聲明,是一些方法特徵的集合,一個接口只有方法的特徵沒有方法的實現,因此這些方法可以在不同的地方被不同的類實現,而這些實現可以具有不同的行爲(功能)。—— 百度百科

但是光看這些冷冰冰的定義,卻很難讓人明白,尤其是對新手來說,爲什麼要用到接口?接口本質作用是什麼?爲了瞭解這個,還是得再次迴歸到現實世界中。想想有身邊哪些接口:Micro usb、Type-C、HDMI……,爲什麼要用到這些接口?因爲手機要連接電源,顯示器要連接電腦……,從中我們進行一次抽象總結:接口是兩種不同事物交互時的一個關卡,更是一組標準,定義了交互雙方所應該遵循的規則。從程序的角度來看:這種規則就是一組相關的功能點的集合。舉個栗子:目前有一個鼠標類,當某天我們這個鼠標類的對象需要與主機類的對象進行交互時,此時就應該去實現一個叫USB的接口,方可進行交互。

從設計的角度來看:接口着眼於某種具體的功能,是一種規範與約束;類着眼於某一類事物的共性,是一種總結與抽象。

三大核心特徵

封裝

這個概念從字面上很容易理解,就是把一堆東西封閉包裝起來。現在我們來深入探究一下其設計內涵。在我看來封裝的好處主要體現在兩點:對外降低複雜度,對內保護數據。其實對於個人開發者來說,一個人寫整個項目,第二點好處並不一定能體會的到。尤其是寫屬性的get()與set()方法之時,總是感覺多此一舉。但是當面對系統性項目需要多人協同工作時,封裝的意義就體現出來了。

第一:可以專人幹專事,每個人管好自己的一畝三分地就OK了,對外暴露自己的實現的功能就行了,而用別人的模塊時也只需要調用相應方法就行了,不用操心其具體實現。

第二:可以防止壞人做壞事,保護核心業務。比如小黑在一個銀行系統項目組中做取款流程開發,當客戶取過錢後小黑需要調用項目主管所提供的

public Boolean updateBalance(Float money,Int operation)

這一方法去修改餘額,而不是能夠直接訪問用戶餘額這一關鍵屬性。如果不進行封裝,當某天主管怒斥了小黑一頓,小黑想搞點破壞,是不是可以把代碼修改成用戶取錢後,不進行減操作,而是直接訪問用戶餘額這一屬性給他加上一些錢哪。

繼承

繼承這一機制估計是大家用得最多的了,通過繼承我們可以很方便地對父類進行修改與拓展。從設計者的角度來看繼承是從抽象到具體的一個過程,架構階段我們基於主要業務邏輯構建出代碼的主框架,建好各種基類,這是一次歸納抽象的過程,細節設計階段我們根據具體業務邏輯與基類,來構造出各種子類,這是一次展開具體化的過程。
流程圖解.png

多態

多態從字面上很容易理解,就是多種形態嘛。孫大聖七十二變,無論是變成石頭、老頭、大樹其本質上都還是個孫悟空,緊箍咒都還對他管用。這樣的好處就是可以屏蔽掉子類對象的差異,使得程序員可以寫出通用性的代碼,而無需針對不同的子類寫不同的代碼,讓代碼更易於拓展。

唐僧的緊箍咒對於孫悟空本身是一個方法,只要一念咒語猴子就頭痛難忍,後來孫悟空變成了一個老頭,唐僧不用專門去針對老頭形態的孫悟空去研究一套緊箍咒,只用念原來的依然奏效。這樣對於唐僧來說緊箍咒就具備的通用性與可拓展性,無論你猴子怎麼變,唐僧都能以不變應萬變!

總結

寶劍都是定型的,而劍術確是靈活的,雖然劍術也有一套規則,但在實戰中是可以千變萬化,形態萬千。所謂好馬配好鞍,互聯網技術日臻成熟,作爲開發者的我們有着數不清的寶劍,但擁有再厲害的寶劍也得配合一套自己了熟於心的劍術才能發揮其威力。程序員也如同劍客一般,劍客之道有三重:

手中有劍,心中有劍,人劍合一,第一境界;

手中無劍,心中有劍,殺人於無形,第二境界;

手中無劍,心中無劍,不武而屈人之兵,此乃第三境界!

不知道作爲程序員的我們現在到哪中境界了哪?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章