1. 程式人生 > >設計模式六大原則簡單總結

設計模式六大原則簡單總結

1.單一職責原則(Single Responsibility Principle)

There should never be more than one reason for a class to change.
應該有且僅有一個原因引起類的變更。這裡也包括介面、方法。

優點

  1. 降低類的複雜性。職責單一,定義明確,自然就變得簡單。由此也陸續引出以下的優點。
  2. 提高可讀性
  3. 提高可維護性。職責單一,將不會出現,修改職責A的邏輯會影響到不需要改變的職責B的邏輯。
  4. 提高擴充套件性

類的單一職責原則

比如,物件的屬性和行為,就應該放到兩個類裡處理。比如對於使用者,使用者的屬性:id、name、age就應該放到UserBO中。而對於使用者行為的處理:新增許可權、修改密碼,就應該放到UserBiz類中處理。因為如果都放到同一個類中處理,則屬性和行為的變更都會引起類的變更,便不符合有且只有一個原因引起變更。

方法的單一職責原則

原方法:changeUserInfo()。其中,修改使用者資訊,同時修改了使用者的名稱、密碼、聯絡方式等等。應改為:

  • changeUserName()
  • changeUserPassWord()
  • changeUserPhone()

便於明確職責。

個人理解

如果職責劃分過細,或者過於追求單一職責原則,會導致類和方法過多。因此,在貫徹單一職責原則的過程中,我們應該首先確認合適的職責範圍,然後在按照單一職責原則進行設計。

2.里氏替換原則(Liskov Substitution Principle,LSP)

定義1:

如果對每一個型別為S的物件o1,都有型別為T的物件o2,使得以T定義的所有程式P在所有的物件o1都代換為o2,程式P的行為沒有發生變化,那麼型別S是型別T的子型別。

定義2:

Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.
所有引用基類的地方必須透明的使用其子類的物件。即:只要父類能出現的地方子類也可以出現,而且替換為子類不會產生任何錯誤或異常,但是反過來就不行,有子類出現的地方,父類未必就能適應

關於繼承

實質上,里氏替換原則是對繼承的使用做出了一定的規範。繼承的優點在於,減少類建立的工作量、提高程式碼複用性、提高類的可擴充套件性等。但繼承也有缺點,即:繼承是侵入性的,只要繼承,就必須擁有父類的所有方法和屬性;降低了程式碼的靈活性,子類必須擁有父類的屬性和方法,讓子類有了一些約束;增加了耦合性,當父類的常量,變數和方法被修改了,需要考慮子類的修改,這種修改可能帶來非常糟糕的結果,要重構大量的程式碼。

里氏替換原則的四個規範

簡單來說,就是子類可以擴充套件父類的功能,但不能改變父類原有的功能。
對於繼承會導致的問題,里氏替換原則規範了四個規範。
1. 子類必須完全實現父類的方法。(即正向,引用基類的地方必須能透明地使用子類物件,且子類不能隨意覆蓋父類的方法,這樣導致子類無法完全替換父類)
2. 子類可以有自己的個性。(即反向,必須引用子類的地方不能以基類代替)
3. 覆蓋或者實現父類的方法時輸入引數可以被放大。(一旦輸入引數不相同,那麼就不是重寫而是過載,那麼如果想實現里氏替換原則,就必須讓父類的引數更小,因為這樣才可以讓替換子類的時候仍使用該方法。例如:父類方法入參為實現類(HashMap),子類方法入參可以為介面(Map),或者子類方法入參(HashMap)為父類方法入參(ConcurrentHashMap)的父類)
4. 覆蓋或者實現父類的方法時輸出結果可以被縮小。

反例

java.sql.Time類,繼承了java.util.Date類。但是他重寫了getDate()、getDay()等方法,直接丟擲了java.lang.IllegalArgumentException()異常,破壞了里氏替換原則。

3.依賴倒置原則(Dependence Inversion Principle ,DIP)

High level modules should not depend upon low level modules,Both should depend upon abstractions.Abstractions should not depend upon details.Details should depend upon abstracts.

  • 高層模組不應該依賴低層模組,兩者都應該依賴抽象
  • 抽象不應該依賴細節
  • 細節應該依賴抽象。

依賴倒置原則在java語言中,表現為:

  • 模組間的依賴通過抽象發生,實現類之間不發生直接的依賴關係,其依賴關係是通過介面或抽象類產生的。
  • 介面或抽象類不依賴實現類
  • 實現類依賴介面或抽象類

依賴倒置原則的核心思想是面向介面程式設計!

舉個例子

比如,作為一個苦逼的碼農(Coder類),每天下班回家(goHome)都要騎摩拜。

public class Mobike {
    public void drive(){
        System.out.print("騎摩拜");
    }
}

public class Coder {
    public void goHome(Mobike mobike){
        mobike.drive();
        System.out.println("回家!");
    }
}

public void offDuty() {
    Coder coder = new Coder();
    Mobike mobike = new Mobike();
    coder.goHome(mobike);
}

執行dip方法,則會輸出“騎摩拜回家!”
然而有一臺,公司上市了!苦逼碼農翻身做主人,財務自由了!於是他買了輛車,以後每天開車回家,美滋滋。

public class Car {
    public void drive(){
        System.out.print("開車");
    }
}

但是goHome方法的入參只能接受Mobike型別的交通工具,Coder和Mobike的耦合性過高,產生了強依賴,所以買了車也沒法馬上開。
如果我們的Coder一開始擁有這樣的駕駛能力,小汽車和摩拜也這樣設計呢?

public interface Vehicle {
    void drive();
}
public class Mobike implements Vehicle{
    public void drive(){
        System.out.print("騎摩拜");
    }
}
public class Car implements Vehicle{
    public void drive() {
        System.out.print("開車");
    }
}
public class Coder {
    public void goHome(Vehicle vehicle){
        vehicle.drive();
        System.out.println("回家!");
    }
}
public void offDuty() {
    Coder coder = new Coder();
    Car mobike = new Car();
    coder.goHome(mobike);
}

這樣的話,我們的高階碼農就可以肆意妄為的想騎車就騎車想開車就開車嘞。

依賴倒置原則的優點

  • 降低類之間的耦合性,提高系統的穩定性,降低修改程式造成的風險
  • 降低並行開發引起的風險與難度

依賴倒置原則的經驗

  • 每個類儘量都有介面或者抽象類,或者抽象類和介面兩都具備。在使用時儘量依賴介面或抽象類使用。
  • 變數的表面型別儘量是介面或者抽象類
  • 任何類都不應該從具體類派生(視情況而定)
  • 儘量不要覆寫基類的方法 。覆蓋基類的方法會影響依賴的穩定性。
  • 結合里氏替換原則使用

4.介面隔離原則

  • 定義1:Clients should not be forced to depend upon interfaces that they
    don’t use.
    客戶端不應該依賴它不需要的介面。
    那依賴什麼呢?依賴它需要的介面,客戶端需要什麼介面就提供什麼介面,把不需要的介面剔除,那就需要對介面進行細化,保證其純潔性。

  • 定義2:The dependency of one class to another one should depend on the
    smallest possible interface.
    類間的依賴關係應該建立在最小的介面上。
    它要求是最小的介面,也是要求介面細化,介面純潔。

這裡的介面指的是:

  • 例項介面(Object Interface) :在 Java 中宣告一個類,然後用 new 關鍵字產生一個例項,它是對一類事物的描述,可以看成是一個介面
  • 類介面(Class Interface):Java中常使用的interface關鍵字定義的介面
    即:建立單一介面,不要建立臃腫龐大的介面。再通俗的說就是介面儘量細化,同時介面中的方法儘量少。我們要為各個類建立專用的介面,而不要試圖去建立一個很龐大的介面供所有依賴它的類去呼叫。

介面隔離即注意控制介面粒度大小,是為了防止我們封裝過度,但是同時設計也是有限度的,我們在實現介面隔離原則時,一定要先滿足單一職責原則

5.迪米特法則(Law of Demeter,LoD)

一個物件應該對其他物件有最少的瞭解。也叫最少知識原則(Low knowledge Principle,LKP),即一個類對自己需要耦合或呼叫的類知道的越少越好。或者用另一個解釋:Only talk to your immediate friends(只與直接朋友通訊)。
迪米特法則是對物件之間的耦合度進行限制,儘量降低類與類之間的耦合。

什麼是朋友

直接的朋友:每個物件都會與其他物件有耦合關係,只要兩個物件之間有耦合關係,我們就說這兩個物件之間是朋友關係。耦合的方式很多,依賴、關聯、組合、聚合等。其中,我們稱出現成員變數、方法引數、方法返回值中的類為直接的朋友。
而出現在區域性變數中的類則不是直接的朋友。也就是說,陌生的類最好不要作為區域性變數的形式出現在類的內部。

注意

既然要避免與非直接的朋友通訊,那就勢必要通過直接的朋友作為中介來間接的與非直接的朋友通訊,這樣會導致系統複雜度變大。所以在採用迪米特法則時要反覆權衡,既做到結構清晰,又要高內聚低耦合。

6.開閉原則

Software entities like classes,modules and functions should be open for extension but closed for modifications.
一個軟體實體如類,模組和函式應該對擴充套件開放,對修改關閉。
即:一個軟體實體應該通過擴充套件來實現變化,而不是通過修改已有的程式碼來實現變化的

為什麼使用開閉原則

  1. 開閉原則是最基礎的設計原則,其它的五個設計原則都是開閉原則的具體形態。
    也就是說其它的五個設計原則是指導設計的工具和方法,而開閉原則才是其精神領袖。依照java語言的稱謂,開閉原則是抽象類,而其它的五個原則是具體的實現類。
  2. 開閉原則可以提高複用性
    在面向物件的設計中,所有的邏輯都是從原子邏輯組合而來,不是在一個類中獨立實現一個業務邏輯。只有這樣的程式碼才可以複用,粒度越小,被複用的可能性越大。
  3. 開閉原則可以提高維護性
    擴充套件一個類比修改一個類要好的多
  4. 面向物件開發的要求

總結

  • 單一職責原則告訴我們實現類要職責單一
  • 里氏替換原則告訴我們不要破壞繼承體系
  • 依賴倒置原則告訴我們要面向介面程式設計
  • 介面隔離原則告訴我們在設計介面的時候要精簡單一
  • 迪米特法則告訴我們要降低耦合
  • 開閉原則是總綱,他告訴我們要對擴充套件開放,對修改關閉

參考文件

相關推薦

設計模式六大原則簡單總結

1.單一職責原則(Single Responsibility Principle) There should never be more than one reason for a class to change. 應該有且僅有一個原因引起類的變更。這裡也包

一句話總結設計模式六大原則

一談到設計模式,相信每一個程式設計師都會用到,有時候即使你沒有刻意的去使用,但是在構建程式碼時也都無形之中用到了它們。因為它們是正確的,是程式碼界的真理。今天在網上搜了搜設計模式,無意之中看到了一篇關於設計模式六大原則的文章,寫的很不錯,開一帖總結整理一下。本文略去一些舉例,

設計模式六大原則之裏氏替換原則

number -h ole 擁有 method about rect sse 程序 1 裏氏替換原則定義 Liskov於1987年提出了一個關於繼承的原則“Inheritance should ensure that any property proved about su

設計模式--六大原則

活性 tro 開閉 拆分 其中 com att 隔離 裏氏替換原則 設計模式六大原則 單一職責原則: 不要存在多於一個導致類變更的原因。**通俗的說,即一個類只負責一項職責 裏氏替換原則: 裏氏替換原則通俗的來講就是:子類可以擴展父類的功能,但不能改變父

設計模式六大原則(6):開閉原則

思考 外部 編程人員 恰恰 單一職責 何事 適應 擴展 分享 開閉原則 定義:一個軟件實體如類、模塊和函數應該對擴展開放,對修改關閉。 問題由來:在軟件的生命周期內,因為變化、升級和維護等原因需要對軟件原有代碼進行修改時,可能會給舊代碼中引入錯誤,也可能會使我們不得不對

設計模式六大原則

編程 color 什麽 例子 進行 函數 細節 增加 客戶 1、開閉原則:Open Close Principle 是軟件實體(類,模塊,函數等)應該可以擴展,但是不可修改。 理解:只以基於原本的來擴展功能,但不能修改原本的代碼。已經面對需求時,對程序的改動是通過增加新

11設計模式六大原則——開閉原則

職責 art 並不是 錯誤 接口 屬於 倒置 編程 探討 定義:一個軟件實體如類、模塊和函數應該對擴展開放,對修改關閉。 問題由來:在軟件的生命周期內,因為變化、升級和維護等原因需要對軟件原有代碼進行修改時,可能會給舊代碼中引入錯誤,也可能會使我們不得不對整個功能進行重構,

java設計模式六大原則

設計者 做的 設計模式 員工 打印 temp 有一種 基於 imp 目錄: 設計模式六大原則(1):單一職責原則 設計模式六大原則(2):裏氏替換原則 設計模式六大原則(3):依賴倒置原則 設計模式六大原則(4):接口隔離原則 設計模式六大原則(5):迪米特法則 設計模式六

設計模式六大原則(2):裏氏替換原則

tr1 裏氏替換原則 style tar 裏氏替換 href target 替換 設計模式 XN潮寺贛3PF鋁73瓷Hhttp://weibo.com/p/1005056364252732 壇2偈6v實8uka誆敲wmhttp://weibo.com/p/10050563

設計模式六大原則(轉)

method 過多 這樣的 不同 提高 依賴倒置 同心圓 23種設計模式 變化 設計模式六大原則(1):單一職責原則 定義:不要存在多於一個導致類變更的原因。通俗的說,即一個類只負責一項職責。 問題由來:類T負責兩個不同的職責:職責P1,職責P2。當由於職責P1需求發

設計模式六大原則(一):單一職責原則

控制 line 避免 多人 由來 pan 兩個類 思想 功能 單一職責定義: 不要存在多於一個導致類變更的原因,通俗的說,即一個類只負責一項職責。 問題由來: 類T負責兩個不同的職責:職責P1,職責P2。當由於職責P1需求發生改變而需要修改類T時,有可能會導致原

設計模式六大原則(4):接口隔離原則

說明 兩個 復雜 試圖 所有 類圖 系統 客戶端 face 定義:客戶端不應該依賴它不需要的接口;一個類對另一個類的依賴應該建立在最小的接口上。 問題由來:類A通過接口I依賴類B,類C通過接口I依賴類D,如果接口I對於類A和類B來說不是最小接口,則類B和類D必須去實現他

[轉]設計模式六大原則[5]:迪米特法則

順序分配 intall 其他 過程 封裝 this 模塊 修改 最好 定義:一個對象應該對其他對象保持最少的了解。 問題由來:類與類之間的關系越密切,耦合度越大,當一個類發生改變時,對另一個類的影響也越大。 解決方案:盡量降低類與類之間的耦合。   自從我們接觸編程開

[轉]設計模式六大原則[6]:開閉原則

說了 一點 模塊 活性 問題 單一職責原則 就是 認識 適應 定義:一個軟件實體如類、模塊和函數應該對擴展開放,對修改關閉。 問題由來:在軟件的生命周期內,因為變化、升級和維護等原因需要對軟件原有代碼進行修改時,可能會給舊代碼中引入錯誤,也可能會使我們不得不對整個功能進行

[轉]設計模式六大原則[4]:接口隔離原則

職責 活性 六大原則 方案 朋友 oid 專用 出現 即使 定義:客戶端不應該依賴它不需要的接口;一個類對另一個類的依賴應該建立在最小的接口上。 問題由來:類A通過接口I依賴類B,類C通過接口I依賴類D,如果接口I對於類A和類B來說不是最小接口,則類B和類D必須去實現他們

Java設計模式六大原則或者說七大原則

設計 sub 隔離 single lose 開閉原則 bili div 依賴倒轉原則 1.開閉原則(Open Close Principle) 2.裏氏代換原則(Liskov Substitution Principle) 3.依賴倒轉原則(Dependence Inver

設計模式-六大原則

改變 開閉 目的 但是 了解 關閉 軟件 設計 模塊 一,單一職責原則 不要存在多於一個導致類變更的原因。 二,裏氏代換原則 子類可以擴展父類的功能,但是不能改變父類原有的功能。 三,依賴倒置原則 高層模塊不應該依賴底層模塊,二者都應該依賴其抽象了;抽象不依賴細節;細節應該

面試寶典-設計模式六大原則

面試 軟件 負責 面向 可維護性 迪米特法則 接口隔離原則 定義 輸入 1、單一職責原則 定義:不要存在多於一個導致類變更的原因。通俗的說,即一個類只負責一項職責。 遵循單一職責原的優點有: 可以降低類的復雜度,一個類只負責一項職責,其邏輯肯定要比負責多項職責簡單的多

JAVA23種設計模式六大原則,資料結構演算法強化訓練

目錄: 設計模式六大原則(1):單一職責原則 設計模式六大原則(2):里氏替換原則 設計模式六大原則(3):依賴倒置原則 設計模式六大原則(4):介面隔離原則 設計模式六大原則(5):迪米特法則 設計模式六大原則(6):開閉原則 設計模式六大原則(1):單一職責原則 定義:不要存在多於一個導致

設計模式六大原則(詳細) 設計模式六大原則

設計模式六大原則 轉自https://www.cnblogs.com/shijingjing07/p/6227728.html 1.設計模式的目的設計模式是為了更好的程式碼重用性,可讀性,可靠性,可維護性。 2.常用的六大設計模式1)單一職責原則2)里氏替換原則3)依賴倒轉原則4)介面