面向對象的六大原則

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

1)單一職責原則

       一個類永遠只有一個職責編程

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

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

2) 里氏替換原則

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

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

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

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

 

  Ps 爲何要叫里氏替換原則呢?這是由於最先提出這個理論的人姓裏Liskov。這是計算機中少有的以姓氏命名的東西。繼承

 3)最少知道原則

      Only talk to your immediate friends。(已經第二次引用英文,是否是很厲害23333)接口

      永遠只和你的朋友交流。

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

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

(2)高內聚:將實現邏輯都封裝在類的內部,對public方法之外的信息,不輕易暴露給外界。這是因爲public對外後,至關因而一種契約,一種許諾。你要再後邊的實現中,不斷的去兼容這種public,以防止調用它的代碼不會報錯。 上面這樣說,可能有點抽象,這裏舉個例子。在不少人對另外一方的要求,都有一條,社會關係不要複雜。爲何會這樣呢?由於一我的若是他和外界的關係越複雜,他就越不穩定,不怕人找事,就怕事找人。或許他的本性是好的,可是周邊的龍魚混雜,三天兩頭的總會有事。避免這種問題的最好辦法,就是一開始就作一個安靜的美男子。  

 

4)接口隔離原則

       一個類對於另一個類的依賴應該創建在最小的接口上。

   一個接口定義的過於臃腫,則表明他的每個實現類都要考慮全部的實現邏輯。若是一個類實現了某個接口,也就是說這個類承載了這個接口全部的功能,維護這些功能成爲了本身的職責。這就無形中增長了一個類的負擔。

這裏有兩點須要說明一下:

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

(2)接口隔離原則和單一原則的區別

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

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

5)依賴置換原則

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

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

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

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

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

6)開閉原則

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

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

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

 

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

 

 

 

做者署名jilodream/王若伊_恩賜解脫(博客連接:http://www.cnblogs.com/jilodream/)

相關文章
相關標籤/搜索