設計模式六大原則
單一職責原則
-
一個方法盡可能做一件事情,一般來說不應該讓一個方法承擔多個職責。
單一職責原則的英文名稱是Single Responsibility Principle,簡稱是SRP。單一職責原則的定義是:應該有且僅有一個原因引起類的變更。
SRP的原話解釋是:There should never be more than one reason for a class to change.
-
單一職責原則提出了一個編寫程序的標准,用“職責”或“變化原因”來衡量接口或設計是否優良,但是“職責”跟“變化原因”都是不好度量的,要“因地制宜”。
-
單一職責適用於接口、類,同時也適用於方法,也就是說,一個方法盡可能做一件事情,一般來說不應該讓一個方法承擔多個職責。
里氏替換原則
-
子類應該能替換掉它的父類。
-
里氏替換原則為良好的繼承定義了一個規范,一句簡單的定義包含了4層含義。
1、子類必須完全實現父類的方法
2、子類可以有自己的個性。
3、覆蓋或實現父類的方法時輸入參數可以被放大。
4、覆寫或實現父類的方法時輸出結果可以被縮小。
-
即如果父類的一個方法的返回值是一個類型T,子類的相同方法(重載或覆寫)的返回值為S,那么里氏替換原則就要求S必須小於等於T,也就是說,要么S和T是同一個類型,要么S是T的子類。
-
好像挺難理解的,查找了一些資料。著名技術作家Robert Martin在1996年為《C++ Reporter》寫了一篇題為《The The Liskov Substitution Principle》的文章,專門介紹LSP。在Martin的文章中,他給了LSP一個解釋:Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it. 意思是:“使用指向基類的指針或引用的函數,必須能夠在不知道具體派生類對象類型的情況下使用它們。”在2002年,Martin在他出版的《Agile Software Development Principles Patterns and Practices》一書中,又進一步簡化為:Subtypes must be substitutable for their base types。子類必須能替換掉它們的父類。這樣理解起來就比較順利了。
依賴倒置原則
-
細節依賴抽象,低層依賴高層。
-
依賴倒置原則的原始定義是: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 abstractions.
包含了三層含義:
1、高層模塊不應該依賴低層模塊,兩者都應該依賴其抽象;
2、抽象不應該依賴細節;
3、細節應該依賴抽象。
-
這一原則在Java語言中的表現就是:
1、模塊間的依賴通過抽象發生,實現類之間不發生直接的依賴關系,其依賴關系是通過接口或抽象類產生的;
2、接口或抽象類不依賴於實現類;
3、實現類依賴接口或抽象類。
-
一般抽象是不變的,而具體是易變的。每個較高層次都為它所需要的服務聲明一個抽象接口,較低的層次實現這些抽象接口,每個高層類都通過該抽象接口使用下一層的服務,接口屬於高層,低層要實現高層的接口,因此現在是低層依賴於高層。是依賴關系倒置和接口所有權的倒置。在周圍環境發生變化的時候,如果設計可以做到不怎么發生改變,那這樣的設計就是好的。
接口隔離原則
-
應該盡量建立單一接口,不要建立臃腫的接口,接口應該盡量細化。
-
接口隔離原則的原始定義是:Clients should not be forced to depend upon interfaces that they don’t use.客戶端不應該依賴它不需要的接口。
-
The dependency of one class to another one should depend on the smallest possible interface.類間的依賴關系應該建立在最小的接口上。
-
這兩個定義概括起來就是,應該盡量建立單一接口,不要建立臃腫的接口,接口應該盡量細化。
接口分離的手段主要有以下兩種:
-
委托分離,通過增加一個新的類型來委托客戶的請求,隔離客戶和接口的直接依賴,但會增加系統開銷。
-
多重繼承分離,通過接口多繼承來實現客戶需求。
迪米特法則
-
一個類應該對自己需要耦合或調用的類知道得最少。
-
迪米特法則(Law of Demeter)又叫最少知道原則(Least Knowledge Principle),1987年秋天由美國Northeastern University的Ian Holland提出,被UML的創始者之一Booch等普及。后來,因為在經典著作《 The Pragmatic Programmer》中提出而廣為人知。
迪米特法則還有一個英文解釋是:Only talk to your immediate friends。
一個對象應該對其他對象有最少的了解。通俗地講,一個類應該對自己需要耦合或調用的類知道得最少。一個類公開的public屬性或方法越多,修改時涉及的面也就越大,變更引起的風險擴散也就越大。在設計時需要反復衡量,是否可以減少public方法和屬性,是否可以修改為private、package-private、protected等訪問權限,是否可以加上final關鍵字等。迪米特法則要求類盡量不要對外公布太多的public方法和非靜態的public變量,盡量內斂,多使用private、package-private、protected等訪問權限。
開閉原則
-
開閉原則要求盡量通過擴展軟件實體的行為來實現變化,而不是通過修改已有的代碼來完成變化。
開閉原則的定義:
Software entities like classes,modules and functios should be open for extemsion but closed for modifications.
-
一個軟件實體如類、模塊和函數應該對擴展開放,對修改關閉。
-
一個軟件產品只要在生命期內,都會發生變化,既然變化是一個既定的事實,我們應該在設計時盡量適應這些變化,以提高項目的穩定性和靈活性。開閉原則要求盡量通過擴展軟件實體的行為來實現變化,而不是通過修改已有的代碼來完成變化。如何做到開閉原則:抽象、封裝。
三大類別
建造型設計模式
在軟件工程中,創建型模式是處理對象創建的設計模式,試圖根據實際情況使用合適的方式創建對象。基本的對象創建方式可能會導致設計上的問題,或增加設計的復雜度。創建型模式通過以某種方式控制對象的創建來解決問題。創建型模式由兩個主導思想構成。一是將系統使用的具體類封裝起來,二是隱藏這些具體類的實例創建和結合的方式。創建型模式又分為對象創建型模式和類創建型模式。對象創建型模式處理對象的創建,類創建型模式處理類的創建。詳細地說,對象創建型模式把對象創建的一部分推遲到另一個對象中,而類創建型模式將它對象的創建推遲到子類中。
讓子類來決定要創建哪個對象。
創建多個產品族中的產品對象。
確保某一個類只有一個實例,並且提供一個全局訪問點。
用來創建復雜的復合對象。
通過復制原型來創建新對象。
結構型設計模式
結構型模式涉及到如何組合類和對象以獲得更大的結構。結構型模式采用繼承機制來組合接口或實現。結構型對象模式不是對接口和實現進行組合,而是描述了如何對一些對象進行組合,從而實現新功能的一些方法。因為可以在運行時刻改變對象組合關系,所以對象組合方式具有更大的靈活性。
將原來不兼容的兩個類融合在一起。
將兩個能夠獨立變化的部分分離開來。
將整體與局部(樹形結構)進行遞歸組合,讓客戶端能夠以一種的方式對其進行處理。
為對象添加新功能。
對外提供一個統一的接口用來訪問子系統。
使用對象池來減少重復對象的創建。
控制客戶端對對象的訪問。
行為型設計模式
行為型模式主要是用於描述類或者對象是怎樣交互和怎樣分配職責的。它涉及到算法和對象間的職責分配,不僅描述對象或者類的模式,還描述了他們之間的通信方式,它將你的注意力從控制流轉移到了對象間的關系上來。行為型類模式采用繼承機制在類間分派行為,而行為型對象模式使用對象復合而不是繼承。
將事件沿着鏈去處理。
將請求封裝成命令,並記錄下來,能夠撤銷與重做。
定義語法,並對其進行解釋。
提供一種方法順序訪問一個聚合對象中的各個元素。
將網狀結構轉變為星型結構,所有行為都通過中介。
保存對象的狀態,在需要時進行恢復。
狀態發生改變時通知觀察者,一對多的關系。
根據不同的狀態做出不同的行為。
封裝不同的算法,算法之間能互相替換。
定義一套流程模板,根據需要實現模板中的操作。
基於穩定數據結構,定義新的操作行為。
注:點擊藍色字體跳轉至原文,《24種設計模式詳解》!
3個月的設計模式篇已完結,接下來全心備戰《微服務與Spring Cloud》
碼字不易,點個在看,點點關注吧!