當前位置:
首頁 > 最新 > java面向對象的六大原則

java面向對象的六大原則

現在編程的主流語言基本上都是面向對象的。如C#,C++,JAVA。我們在使用時,已經構造了一個個的類。但是往往由於我們在類內部或外部的設計上存在種 種問題,導致儘管是面向對象的語言,卻是面向過程的邏輯,甚至維護起來異常困難。每次增加或修改功能都要改動很多的代碼,如履薄冰。而面向對象的六大原則 主要的目的,就是我們如何設計類,更能很好的利用面向對象的特性。

單一職責原則

一個類永遠只有一個職責。

一套軟體就像是一個團隊,每個類就是團隊中的一個成員。團隊如果想穩定的發展。這些類就要各司其職,分工明確。如果類之間的功能出現了混淆,那麼軟體的 整體結構就會非常的混亂。就像管理學中的一句話,如果一個職責由每個員工負責,那麼這個職責就沒有員工在負責。 這個原則的概念非常簡單,也是非常基礎的。很多人儘管沒有學習過面向對象的思想,但是經常寫代碼之後也會不自覺的遵守這個原則。

Ps: 在遵循單一職責原則的時候,常常會遇到職責擴散的問題。什麼是職責擴散呢?這裡簡單說下,在日誌生活中,我們在分類職責時,發現很多平常不受重視的職責, 但是這些職責又不能忽視。於是就依次累加,最後分起類來會無窮無盡(有興趣的讀者可以參考下長尾定理)。為了解決這種問題,我們就需要有一些類,他的職責 比較綜合(類似於「其它」)。類似於一個幫助類。但是這個類又不能太複雜了,否則我們就應該考慮怎麼把這個類分離開來。究竟這個類的複雜程度到了什麼時候 情況下,我們就應該拆分呢?這個需要程序員根據軟體自身的複雜情況來判斷,沒有一個統一的標準。

里氏替換原則

「Inheritance should ensure that any property proved about supertype objects also holds for subtype objects.」

——「繼承必須確保超類所擁有的性質在子類中仍然成立「

這個原則主要是為了體現面向對象的「繼承」特徵來提出的。 它的主旨就是,能夠使用基類的地方,必然也能夠透明的使用其子類,並且保證不會出錯。為了保證這種透明的無差別的使用,子類在使用時不應該隨意的重寫父類 已經定義好的非抽象的方法。因為這些非抽象方法,類似於某種職能或契約,當父類保持這種約定時,子類也應該遵循並保證該特性,而非修改該特性。 我們在寫代碼的時候,如果一個參數設定的是基類(或介面、抽象類),那麼我們傳送子類進去,一樣可以正常使用。因為基類相對於父類,只是一個更豐富,更具體,更詳細的表現形式。而不應該出現,傳入父類運行某種方法沒有問題,可是傳入子類運行時就報錯了。這在日常生活中也可以理解,汽車作為父類,他下面有卡車、 轎車。轎車下邊又有兩廂,三廂等不同的繼承。但是無論是哪種汽車(父類)的職能,對於他的子類(卡車或轎車)都應該具有相同的職能,而不是相反的職能。以 至於子類的子類(本例中是兩廂轎車)也應該擁有汽車一致的功能。

我們在寫代碼中,很容易出現複寫了父類的方法後,父類的方法發生了改動,而未考慮到子類的方法也需要作出相應的改動,導致代碼出現錯誤。 通俗一點,可以理解為子類是遺傳自父類的。他在各種職能上也應該一脈相承自父類。而不應該隨意改變。

Ps:為什麼要叫里氏替換原則呢?這是因為最早提出這個理論的人姓里Liskov。這是計算機中少有的以姓氏命名的東西。

最少知道原則

Only talk to your immediate friends。永遠只和你的朋友交流。

我們在學習編程的初期,都會有人告訴我們要遵循「高內聚,低耦合」。而OO中也將「封裝」作為對象的基本特徵之一。最少知道原則其實體現的就是「高內聚,低耦合」這句話。

(1)低耦合:一個類對於自己依賴的類,知道的越少越好。不要讓一個類依賴過多的類。否則這個類很容受外界的影響,並且因為這種影響要改變自身的代碼(自身要適應)。

(2) 高內聚:將實現邏輯都封裝在類的內部,對public方法以外的信

息,不輕易暴露給外界。

這是由於public對外後,相當於是一種契約,一種許諾。你要 再後邊的實現中,不斷的去兼容這種public,以防止調用它的代碼不會報錯。 上面這樣說,可能有點抽象,這裡舉個例子。在很多人對另一方的要求,都有一條,社會關係不要複雜。為什麼會這樣呢?因為一個人如果他和外界的關係越複雜, 他就越不穩定,不怕人找事,就怕事找人。或許他的本性是好的,但是周邊的龍魚混雜,三天兩頭的總會有事。避免這種問題的最好辦法,就是一開始就做一個安靜 的美男子。

介面隔離原則

一個類對於另外一個類的依賴應該建立在最小的介面上。

一個介面定義的過於臃腫,則代表他的每一個實現類都要考慮所有的實現邏輯。如果一個類實現了某個介面,也就是說這個類承載了這個介面所有的功能,維護這些功能成為了自己的職責。這就無形中增加了一個類的負擔。

這裡有兩點需要說明一下:

(1)介面定義的小,但是要有限度。對介面細化可以增加靈活性,但是過度細化則會使設計複雜化。同時介面的使用率不高,提高了代碼的維護成本。這種極端的體現就是每個介面只含有一個方法,這顯然是不合適的。

(2)介面隔離原則和單一原則的區別

共同點:都是儘可能的縮小涉及的範圍。

不同點:單一原則主要是指封裝性。他針對的是一個類、一個方法,是從對象的角度考慮的。而介面隔離原則是指類之間的耦合應該保持的一個度。他針對的是類(對象)和類(對象)之間的關係。如果說單一原則指的是思想單純,那麼接 口隔離指的就是社會關係簡單啦。

依賴置換原則

這個原則的名字比較唬人,我們先看看他的內容究竟是什麼。在設計模式中對該原則有兩句經典的描述:

(1)高層模塊不應該依賴底層模塊。兩者都應該依賴抽象。

(2)抽象不應該依賴細節,細節應該依賴抽象。

這兩句話的含義是:高層模塊不應該依賴底層模塊。兩者應該通過抽象的東西進行關係鏈接(抽象的東西是指介面或者抽象類)。其次抽象類或者一個介面不應該依賴某個實現類。而這些實現類反而應該依賴於這個抽象類的設定。

通俗一點的說法就是,模塊之間不應該直接產生調用關係(這是舊有的調用關係),兩者應該通過面向介面(或者理解為面向設定的契約)進行編程。而這些契約和接 口更不應該以來自底層模塊而設定。這些底層模塊反而應該遵守這些契約。因為契約(抽象類、介面)相對於哪些實現代碼,更不會改變,也就是更穩定。所以依賴 置換原則又叫作面向介面編程或面向契約編程。本意就是調整原來的依賴關係,重行進行了設定。

開閉原則

開閉原則是指:一個軟體、一套系統在開發完成後,當有增加或修改需求時,應該對拓展代碼打開,對修改原有代碼關閉。

類一旦確定,就不應該再對其功能發生修改。這 是面向對象設計中,最重要最核心的原則。方案發布後,我們最擔心的是什麼?就是需求的變化,而需求一旦有變化,就要修改代碼。大部分的bug往往就是這時 候引入的。因為修改代碼時,我們往往將重點放在,如何解決當前bug上,反而沒有注意因為這個修改,對原有設計的影響。

這條原則沒有具體的指導要求,是前邊五條原則的根本。

ps: 這六個面向對象的原則,並不是是和否的問題,也不是遵守和不遵守的問題。而是遵守的多和遵守的少的問題。我在文中也多次強調,我們在設計時,應該注意把握 一個度。誠然儘可能的遵守這些原則,會使代碼維護起來更容易。但是維護粒度過細,所需要的設計和開發成本成倍增加,這顯然是捨本逐末的。如圖,面向對象開 發原則可以從以下這個坐標圖展示,不論是哪個維度,他的值都不應該過滿,甚至溢出,當然也不能很低,保持一個適當的度即可。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 java學習吧 的精彩文章:

Java反射獲取類和對象信息全解析
java技術團隊必須要注意的那幾個點
給初學者的建議 中
給java初學者建議 下-1
熟悉java三大框架的作用

TAG:java學習吧 |

您可能感興趣

Perl 面向對象
Lua 面向對象
AppleCare+ for Mac正式面向中國市場推出
Python入門基礎之面向對象四:運算符重載
蘋果AppleCare+for Mac正式面向中國市場推出
TensorFlow官方最新tf.keras指南:面向對象構建深度網路
Python指南:面向對象程序設計
面向不同需求的對象存儲系統對比:Ceph與Swift
谷歌 I/O 開發者大會上的 Smart Compose 功能開始面向 Gmail 桌面用戶公測
谷歌宣布進一步擴大面向黑人工程師的Howard West項目
三星或正在研發第二款Bixby智能音箱,對標Google Home Mini面向低端市場
Facebook Reality Labs正式成立面向VR/AR開發
思科聯合Pure Storage發布面向AI的FlashStack融合系統
IBM宣布推出面向雲原生應用的Microclimate開發平台
聯想推出三款面向教育市場的Chromebook筆記本
Google面向入門用戶的Android Go,現在有一個好的開始
Dell宣布與Google合作:面向商務領域推出Chromebook
Arm發布面向數據中心和5G網路的兩款Neoverse晶元新品
面向未來的工作?——《Unnatural death》告訴你
全新 iPad mini 5 設計不變,仍面向低端市場