1. 程式人生 > >【JAVA設計模式】設計六大原則

【JAVA設計模式】設計六大原則

- 單一職責原則(SRP)

定義:就一個類而言,應該僅有一個引起它變化的原因。
從這句定義我們很難理解它的含義,通俗講就是我們不要讓一個類承擔過多的職責。如果一個類承擔的職責過多,就等於把這些職責耦合在一起,一個職責的變化可能會削弱或者抑制這個類完成其他職責的能力。這種耦合會導致脆弱的設計,當變化發生時,設計會遭受到破壞。
比如我經常看到一些Android開發在Activity中寫Bean檔案,網路資料處理,如果有列表的話Adapter 也寫在Activity中,問他們為什麼除了好找也沒啥理由了,把他們拆分到其他類豈不是更好找,如果Activity過於臃腫行數過多,顯然不是好事,如果我們要修改Bean檔案,網路處理和Adapter都需要上這個Activity來修改,就會導致引起這個Activity變化的原因太多,我們在版本維護時也會比較頭疼。也就嚴重違背了定義“就一個類而言,應該僅有一個引起它變化的原因”。
當然如果想爭論的話,這個模式是可以引起很多爭論的,但請記住一點,你寫程式碼不只是為了你也是為了其他人。


- 開放封閉原則(ASD)

定義:類、模組、函式等等等應該是可以拓展的,但是不可修改。
開放封閉有兩個含義,一個是對於拓展是開放的,另一個是對於修改是封閉的。對於開發來說需求肯定是要變化的,但是新需求一來,我們就要把類重新改一遍這顯然是令人頭疼的,所以我們設計程式時面對需求的改變要儘可能的保證相對的穩定,儘量用新程式碼實現拓展來修改需求,而不是通過修改原有的程式碼來實現。
假設我們要實現一個列表,一開始只有查詢的功能,如果產品又要增加新增功能,過幾天又要增加刪除功能,大多數人的做法是寫個方法然後通過傳入不同的值來控制方法來實現不同的功能,但是如果又要新增功能我們還得修改我們的方法。用開發封閉原則解決就是增加一個抽象的功能類,讓增加和刪除和查詢的作為這個抽象功能類的子類,這樣如果我們再新增功能,你會發現我們不需要修改原有的類,只需要新增一個功能類的子類實現功能類的方法就可以了。


- 里氏替換原則(LSP)
定義:所有引用基類(父類)的地方必須能透明地使用其子類的物件
里氏代換原則告訴我們,在軟體中將一個基類物件替換成它的子類物件,程式將不會產生任何錯誤和異常,反過來則不成立,如果一個軟體實體使用的是一個子類物件的話,那麼它不一定能夠使用基類物件。
里氏代換原則是實現開閉原則的重要方式之一,由於使用基類物件的地方都可以使用子類物件,因此在程式中儘量使用基類型別來對物件進行定義,而在執行時再確定其子類型別,用子類物件來替換父類物件。
在使用里氏代換原則時需要注意如下幾個問題:

  1. 子類的所有方法必須在父類中宣告,或子類必須實現父類中宣告的所有方法。根據里氏代換原則,為了保證系統的擴充套件性,在程式中通常使用父類來進行定義,如果一個方法只存在子類中,在父類中不提供相應的宣告,則無法在以父類定義的物件中使用該方法。
  2. 我們在運用里氏代換原則時,儘量把父類設計為抽象類或者介面,讓子類繼承父類或實現父介面,並實現在父類中宣告的方法,執行時,子類例項替換父類例項,我們可以很方便地擴充套件系統的功能,同時無須修改原有子類的程式碼,增加新的功能可以通過增加一個新的子類來實現。里氏代換原則是開閉原則的具體實現手段之一。
  3. Java語言中,在編譯階段,Java編譯器會檢查一個程式是否符合里氏代換原則,這是一個與實現無關的、純語法意義上的檢查,但Java編譯器的檢查是有侷限的。

- 依賴倒置原則(DIP)
定義:高層模組不應該依賴低層模組,兩個都應該依賴於抽象。抽象不應該依賴於細節,細節應該依賴於抽象。
在Java中,抽象就是指介面或者抽象類,兩者都是不能直接被例項化的;細節就是實現類,實現介面或者繼承抽象類而產生的就是細節,也就是可以加上一個關鍵字new產生的物件。高層模組就是呼叫端,低層模組就是具體實現類。
依賴倒置原則在Java中的表現就是:模組間通過抽象發生,實現類之間不發生直接依賴關係,其依賴關係是通過介面或者抽象類產生的。如果類與類直接依賴細節,那麼就會直接耦合,那麼當修改時,就會同時修改依賴者程式碼,這樣限制了可擴充套件性。


- 迪米特原則(LOD)
定義:一個軟體實體應當儘可能少地與其他實體發生相互作用。
也稱為最少知識原則。如果一個系統符合迪米特法則,那麼當其中某一個模組發生修改時,就會盡量少地影響其他模組,擴充套件會相對容易,這是對軟體實體之間通訊的限制,迪米特法則要求限制軟體實體之間通訊的寬度和深度。迪米特法則可降低系統的耦合度,使類與類之間保持鬆散的耦合關係。
迪米特法則要求我們在設計系統時,應該儘量減少物件之間的互動,如果兩個物件之間不必彼此直接通訊,那麼這兩個物件就不應當發生任何直接的相互作用,如果其中的一個物件需要呼叫另一個物件的某一個方法的話,可以通過第三者轉發這個呼叫。簡言之,就是通過引入一個合理的第三者來降低現有物件之間的耦合度。
在將迪米特法則運用到系統設計中時,要注意下面的幾點:在類的劃分上,應當儘量建立鬆耦合的類,類之間的耦合度越低,就越有利於複用,一個處在鬆耦合中的類一旦被修改,不會對關聯的類造成太大波及;在類的結構設計上,每一個類都應當儘量降低其成員變數和成員函式的訪問許可權;在類的設計上,只要有可能,一個型別應當設計成不變類;在對其他類的引用上,一個物件對其他物件的引用應當降到最低。


- 介面隔離原則(ISP)
定義:一個類對另一個類的依賴應該建立在最小的介面上。
建立單一介面,不要建立龐大臃腫的介面,儘量細化介面,介面中的方法儘量少。也就是說,我們要為各個類建立專用的介面,而不要試圖去建立一個很龐大的介面供所有依賴它的類去呼叫。
採用介面隔離原則對介面進行約束時,要注意以下幾點:

  1. 介面儘量小,但是要有限度。對介面進行細化可以提高程式設計靈活性,但是如果過小,則會造成介面數量過多,使設計複雜化。所以一定要適度。
  2. 為依賴介面的類定製服務,只暴露給呼叫的類它需要的方法,它不需要的方法則隱藏起來。只有專注地為一個模組提供定製服務,才能建立最小的依賴關係。
  3. 提高內聚,減少對外互動。使介面用最少的方法去完成最多的事情.