程序員不得不知的設計模式

設計模式目的

提高軟件的可維護性、通用性、可擴展性;並降低軟件複雜度

程序員不得不知的設計模式

Java 設計模式

四大發明之活字印刷

可維護

可複用

可擴展

靈活性

開發原則

單一職責原則

功能儘量單一

根據業務複雜度:可以在方法層面實現職責單一,也可以在類層面實現職責單一

依賴倒轉原則

抽象不應該依賴細節,細節應該依賴於抽象

面向接口編程,不要對實現編程

里氏代換原則

子類型必須能夠替換掉父類型

所有引用基類的地方必須能夠透明的使用子類對象

實際是儘量避免子類對父類方法的重寫

如果必須使用:則可通過聚合、組合、依賴等方案

開放封閉原則

對擴展開放

對更改封閉

迪米特法則

即最少知道原則(一個類對自己依賴的類知道的越少越好。無論被依賴的類多麼複雜,都應該將邏輯封裝在方法的內部,通過public方法提供給外部。這樣當被依賴的類變化時,才能最小的影響該類)

只要兩個對象之間有耦合關係,即稱為朋友關係(耦合關係:組合、聚合、依賴、關聯)

更簡單的定義:只與【直接】朋友通信

迪米特法則的核心是降低耦合關係,但不能完全無耦合關係

合成複用原則

降低耦合性

儘量使用合成/聚合的方式,而不是使用繼承

接口隔離??

創建型

Singleton:單例模式

在軟件系統中,保證一個類僅有一個實例,並提供一個全局訪問點

創建方式

餓漢模式

靜態常量

靜態代碼塊

優點:在類裝載時完成實例化,操作簡單,避免線程同步問題;

缺點:沒有達到lazy loader效果,可能造成內存浪費

懶漢模式

線程不安全

優點:起到lazy loader效果,不浪費內存;【在單線程下才能使用】

缺點:線程不安全

實際開發中不建議使用

線程安全(同步方法)

優點:起到lazy loader作用,不浪費內存,同時解決線程安全問題

缺點:因為每次獲取實例時都要進行同步。性能低下

實際開發中不建議使用

線程安全(同步代碼塊)

缺點:起不到線程安全作用

直接不能用

雙重校驗

對象定義時添加volitile關鍵字

同步代碼塊出進行雙重檢查

public static Object getInstance(){}

優點:既保證線程安全,也保證了效率。

邏輯說明:先判斷是否為null,避免了同步延時;在進入同步時再判斷是否已經實例化,避免創建多個實例

靜態內部類

特點:當外部類被裝載時,靜態內部類不會被裝載;當內部類被調用時內部類才會被裝載(而且只裝載一次,因此是線程安全的)

類的靜態屬性只會在第一次加載時初始化,JVM保證了線程的安全性

枚舉

優點:不僅避免了多線程問題,而且還避免反序列化創建新的對象

實例:Hibernate中的SessionFactory、JDK中的Runtime(餓漢模式)

使用場景:需要頻繁的創建和銷燬的對象,對象創建比較耗時;如:經常使用的對象、工具類對象、頻繁訪問數據庫或文件的對象等

工廠模式

簡單工廠模式

優點:工廠類中包含了必要的邏輯判斷,根據客戶端條件動態實例化相關類;對客戶端來說,去除了與具體產品的依賴。

實例:JDK中Calendar.getInstance

工廠方法模式

定義:定義一個用於創建對象的抽象方法,讓子類決定實例化的類,工廠方法使得一個類的實例化延遲到其子類中。

父類創建一個抽象方法由子類實現

抽象工廠模式

提供創建一系列相關或相互依賴對象的接口,而無需指定他們具體的類

Prototype:原型模式

定義:用原型實例制定創建對象的種類,並且通過拷貝這些原型創建新的對象

對象實現接口Cloneable中的clone方法

優點:

1、一般在初始化信息不發生變化的情況下,克隆是最好的方式,既隱藏了對象創建的細節,有大大提高性能。

2、不用重新初始化對象,而是動態的獲取對象運行時的狀態。

淺複製與深複製:如果類型是值類型,則逐個複製;若為引用類型,則複製引用地址,那麼原始對象與複本引用同一對象(即副本改變則原對象改變)。

深拷貝實現

clone方式

Object clone = super.clone();

序列化實現

相對於clone方式,避免了對象中多個引用類型的遍歷處理

Builder:建造者模式

也叫生成器模式

定義:將一個複雜對象的創建與其表示分離,使其同樣的構建過程可以創建不同的表示。

應用場景:當創建複雜對象的算法應獨立於實現過程

實例:jdk中StringBuilder

結構型

Adapter:適配器模式

定義:將一個類的接口轉換成客戶希望的另外一個接口;使不兼容的接口通過適配可兼容工作

適配器類型:類適配器、接口適配器、對象適配器

實例:SpringMVC中的HandlerAdapter

DispatchServlet根據請求controller類型獲取對應的HandleAdapter,然後根據handleAdapter調用具體的controller實現

參考:姚明需要翻譯

Bridge:橋接模式

定義:將抽象部分與他的實現部分相分離,使他們都可以獨立的變化

基於類的最少設計原則

實例:JDBC

參考:手機與軟件

Decorator:裝飾模式

動態的給一個對象添加額外的職責,就增加功能來說,比生成子類更靈活

實例:FilterInputStream

Composite:組合模式

定義:將對象組合成樹形結構以表示“部分-整體”的層次結構。組合模式使得用戶對單個對象和組合對象的使用具有一致性。

應用場景:體現部分與整體層次的機構時,以及希望用戶可以忽略組合對象與單個對象的不同,統一的使用組合結構中的所有對象時。

實例:HashMap

參考:辦公OA系統

Facade:外觀模式

為子系統中的一組接口提供一個一致的界面,定義一個高層接口,這個接口使得這一子系統更加容易使用

也稱過程模式

實例:mybatis

參考:xfunds的control類即採用該設計模式

Flyweight:享元模式

定義:運用共享技術有效的支持大量細粒度對象

優點:可以避免大量非常相似類的開銷。在程序設計中有時需要生成大量細粒度的類實例來表示數據。如果能發現這些實例除了參數基本都是相同的,有時就能能夠大幅度的減少需要實例化的類的數量。如果能把那些參數移到類實例的外面,在方法調用時將他們傳遞過來,就可以通過共享大幅度的減少單個實例的數目。

認清內部狀態外部狀態

參考:網站共享、基本類型包裝類、共享池等(數據庫連接池、String常量池等)

jdk實例:Integer中valueOf方法-128~127

Proxy:代理模式

為其他對象提供一種代理以控制對這個對象的訪問

優點:對功能進行增強

動態代理:使用反射和字節碼技術,在運行期創建指定接口或類的子類,以及其實例對象的技術。通過該技術可以無侵入的對代碼進行增強

jdk動態代理

cglib動態代理

基於ASM的字節碼生成庫,允許在運行時對字節碼進行修改和動態生成。

被代理類不能為final類

代理類實現MethodIntercept,並實現intercept方法;獲取實例getInstance{Enhance eh = new Enhance();eh.setSuperClass;eh.setCallback;eh.create}

幾種代理變體:

1、遠程代理

2、虛擬代理

3、安全代理

4、智能指引

行為型

Strategy:策略模式

定義了算法家族,分別封裝起來,讓他們之間可以互相替換,此模式讓算法的變化不會影響到客戶的使用

策略模式的Strategy類層次為Context定義了一系列可供重用的算法或行為;繼承有助於析取出這些算法中的公共功能

State:狀態模式

定義:當一個對象的內在狀態改變時允許改變其行為,這個對象看起來像是改變了其類

目的:當控制一個對象的狀態轉換的條件表達式過於複雜時的情況,把狀態的判斷邏輯轉移到表示不同狀態的一系列類中,把複雜的判斷邏輯簡單化

在多種狀態轉換時,對外輸出不同的行為。狀態與行為一一對應,狀態見可相互轉化

Template:模板方法模式

定義:定義一個操作中的算法的框架,而將一些步驟延遲到子類中。使得子類可以不改變一個算法的結構即可重定義該算法的某些特定步驟

應用場景:當我們要完成某一細節層次一致的一個過程或一系列步驟,但其個別步驟在更詳細的層次上的實現可能不同時,通常採用模板方法模式

參考:抄試卷、類的繼承等

Observer:觀察者模式

Iterator:迭代器模式

定義:提供一種方法順序閥訪問一個聚合對象中各個元素,而又不暴露內部表示

分離了集合對象的遍歷行為,抽象出一個迭代器類來負責,這樣既可以做到不暴露內部集合的結構,又可以讓外部代碼透明的訪問集合的內部數據

參考:公交乘務員售票

Chain of Responsibility:責任鏈模式

OA系統的審批流程

springmvc中請求處理流程

Command:命令模式

定義:將一個請求封裝為一個對象,從而使你可用不同的請求對客戶參數化,對請求排隊或記錄日誌,以及支持可撤銷操作

Memento:備忘錄模式

定義:在不破壞封裝性的前提下,捕獲一個對象的內部狀態,並在該對象之外保存該狀態。這樣以後就可以將該對象恢復到原先保存的狀態。

應用場景:電腦設置還原點

Visitor:訪問者模式

定義:表示一個作用於某對象結構中的各元素的操作。它使你可以在不改變各元素的類的前提下定義作用於這些元素的新操作。

將數據結構與數據操作分離

缺點:不利於維護

Mediator:中介模式

定義:用一箇中介對象來封裝一系列的對象交互。中介者使各對象不需要顯示的相互引用,從而是耦合鬆散,而且可以獨立的改變他們之間的交互。

子主題 2

Interpreter:解釋器模式

定義:給定一個語言,定義它的文法的一種表示,並定義一個解釋器。這個解釋器使用該表示來解釋語言中的句子

應用場景:正則表達式

UML類圖

語言語法

依賴

依賴:虛線箭頭

實現【依賴特例】

表達方式:空心三角形+虛線

泛化(即繼承)【依賴特例】

表達方式:空心三角形+實線

關聯【依賴特例】

表達方式:實線箭頭

聚合

局部與整體可以分割

表達方式:空心菱形+實線箭頭

組合

局部與整體不可分割

表達方式:實心菱形+實線箭頭


分享到:


相關文章: