設計模式及相似模式對比

寫在前面

很久沒有這麼大塊的時間去重溫設計模式了,這正好整理一下;
本篇博文包含基礎設計模式的概念,以及相似設計模式之間的區別,以便於理解。
後續會持續更新

六大原則

(理解是啥就行)
單一職責原則:一個類應該只有一個引起變化的原因、
里氏替換原則:任何使用父類對象地方都可以用其子類對象無縫替換、
依賴倒置原則:依賴於接口,而非實現編程、
接口隔離原則:最小接口原則、
迪米特法則:一個類應該於儘可能少的類打交道,減少系統複雜度、
開閉原則:對擴展開放,對修改封閉

策略模式

定義算法族(以組合方式依賴於一個接口),分別封裝起來(依賴於接口編程),讓他們之間可以相互替換(使用set方法替換接口指向的算法對象),讓算法的變化獨立於使用算法的客戶;
封裝變化

觀察者模式

定義了對象之間一對多依賴關係,當一對象改變時,它所有的依賴者都會接到通知並自動更新。
根據依賴倒置原則,所有依賴者實現共同接口(觀察者),接口中定義被觀察者改變時的更新操作,被觀察者依賴於觀察者共同的接口;
被動接受與主動獲取:被觀察改變時,只通知所有觀察它的狀態改變,而非直接推送數據,觀察者依賴被觀察者,可在觀察者接口中主動獲取被觀察者的數據;

裝飾模式

定義一個新的接口實現類,以組合的方式動態擴展原有實現類的功能(二者實現同一接口)。
開閉原則:對擴展開發,對修改關閉,(設計程序是,應該允許行爲被擴展,而無需修改原有代碼)
java單繼承,避免繼承是保證java代碼更具擴展性的條件之一
與繼承相比,組合方式更具有彈性,可以在運行時動態的加入新的行爲;
裝飾模式使用過程中會有許多小的對象,裝載麻煩,典型案例:java源碼中的io包;

工廠模式

簡單工廠、工廠方法、抽象工廠
封裝創建對象的代碼,使客戶端與具體的實現類解耦,客戶端只需面向接口編程,而不知道運行時到底是哪個對象在執行(依賴於接口,而非具體類);
依賴倒置原則:客戶端只需要依賴於工廠及產品接口,而無需依賴於衆多的產品實現類;
類的實例化是無法避免的,工廠的作用是將所有實例化對象的代碼集中在一起,避免重複,也便於維護;
工廠方法模式則將要實例化的類推遲到工廠接口的子類,創建者並不知道要創建的具體產品是什麼,在新增產品實現時也無需修改創建者的代碼;
抽象工廠模式:提供一個接口,用於創建相關對象的家族,具體創建由其實現完成(與具體產品類耦合);
區別於工廠方法模式的是,抽象工廠的作用是創建並組合一組對象;

單例模式

確保一個類只有一個實例,並提供全局訪問點;
主要思路是:構造函數私有化,靜態方法獲取實例;
餓漢式、懶漢式、同步方法式懶漢(避免多線程問題);
雙重檢查式:只需要在第一次獲取實例時才需要使用同步(需要使用volatile修飾引用,以便多線程環境下每次使用該對象都去內存中取最新的值,用完後也將最新值寫會內存(而不是緩存);
靜態類部類:在單例類中定義靜態類部類(只在第一次調用時纔會裝載,因此靜態類部類中使用餓漢式初始化);
構造方法私有化並不能避免使用反射來初始化一個新的對象;
枚舉:既避免反射 又避免反序列化
反射:在通過newInstance創建對象時,會檢查該類是否ENUM修飾,如果是則拋出異常,反射失敗
反序列化:在反序列化枚舉常量時,readObject方法會根據類信息獲取枚舉常量列表中已經存在的枚舉對象
枚舉實現代碼如下:

public enum EnumSingleton {
    INSTANCE;
    public EnumSingleton getInstance(){
        return INSTANCE;
    }
}

命令模式

將請求封裝成對象(只暴露出execute方法,execute方法會調用receiver的動作),請求調用者set該對象,調用該對象的execute方法執行receiver的方法;
目的:實現請求調用者和請求接收者之間的解耦(無論接收者如何複雜,都由命令對象一個一個封裝),請求調用者無需關心該命令怎麼執行,只需知道執行命令對象的execute方法就能實現該命令對象代表的動作;
用途:

  1. 封裝衆多五花八門的接收者,使得調用者無需編寫大量代碼適配
  2. 隊列請求(工作隊列與算法對象完全解耦,命令對象實現命令接口,調用者只需一個一個只需命令接口對象的方法,無需知道具體執行什麼操作)
  3. 日誌請求(大型數據結構調用的時避免系統崩潰數據丟失,保存日誌用於數據恢復)

適配器模式

將一個類的接口,轉換爲客戶期望的另一個接口,讓原本無法協作不兼容的類可以合作無間;
比如讓火雞僞裝成鴨子;
與裝飾模式的區別:
都是對原有的類進行包裝,但意圖不一樣,
裝飾模式用於在原來基礎上新增功能而不改變原有接口,而適配器模式是將原來的接口改造爲另一個接口;

外觀模式

提供一個統一的接口,用來訪問子系統中的一羣接口,即定義了一個更高層的接口,讓子系統更容易使用;
迪米特法則:最少知識原則,不要讓太多類耦合在一起,避免修改系統中一部分時影響到其他部分;

適配器模式、外觀模式、裝飾模式對比

需要使用一個現有類而這個類並不完全符合要求時使用適配器模式;
當需要簡化一個很大子系統時使用外觀模式;
當需要給一個類添加功能而不改變原有接口時使用裝飾模式;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章