Head First設計模式筆記
一、設計原則
1、找到應用中可能需要變化之處,把它們獨立出來,不要和不需要變化的程式碼混在一起
把會變化的部分取出並“封裝”起來,好讓其他部分不會受到影響。
2、針對介面程式設計,而不是針對實現程式設計
3、多用組合,少用繼承
4、為了互動物件之間的鬆耦合設計而努力,將物件間的依賴關係降到最低。
5、類應該對擴充套件開放、對修改關閉。
目標是允許類容易擴充套件,在不修改現有程式碼的情況下,就可搭配新的行為,這樣的設計具有彈性可以應對改變,可以接受新的功能來應對改變的需求。
6、依賴倒置原則:要依賴抽象,不要依賴具體類。
不能讓高層元件依賴低層組建,而且,高層元件與低層元件都要依賴抽象類。
7、最少知識原則
在系統設計中,不讓太多的類耦合在一起,增加維護成本
8、好萊塢原則
在好萊塢原則下,我們允許低層元件將自己掛鉤到系統上,但是高層元件會決定什麼時候和怎樣使用這些低層元件,絕不允許低層元件直接呼叫高層元件
9、單一職責
一個類應該只有一個引起變化的原因
二、設計模式
1、策略模式
策略模式定義了“演算法族”,分別封裝起來,讓它們直接可以相互替換,此模式讓演算法的變化獨立於使用它對的客戶
2、觀察者模式
觀察者模式定義了物件之間的一對多依賴,這樣一來,當一個物件改變狀態時,它的所有依賴者都會收到通知並自動更新。
例:java.util.Observer、java.util.Observable
Observer介面
public interface Observer {
void update(Observable o, Object arg);
}
約定了觀察者的行為。當被觀察物件狀態改變時,觀察者做出反應的就是update方法。方法有兩個引數,第一個引數是被觀察物件的引用,方便觀察者主動拉取資料;第二個引數 呼叫者呼叫Observable例項的notifyObservers(Object obj)方法時傳入的,表示向觀察者推送資料。
Observable類
public class Observable {
private boolean changed = false;
private Vector obs;
public Observable(){};
protected synchronized void setChanged(){};
protected synchronized void clearChanged(){};
public synchronized void addObserver(Observer o){};
public synchronized void deleteObserver(Observer o) {};
public synchronized void deleteObservers(){};
public synchronized boolean hasChanged(){};
public synchronized int countObservers(){};
public void notifyObservers(){};
public void notifyObservers(Object arg){};
}
Observable類有一個變數changed,代表是否方法改變,提供具體業務一種決定是否向觀察者推送的方式。
3、裝飾者模式
裝飾者模式動態地將責任附加到物件上。
1)、裝飾者與被裝飾者有相同的超型別。
2)、可以用一個或多個裝飾者包裝一個物件。
3)、在任何需要原始物件的場景,可以使用裝飾它的物件代替它。
4)、裝飾者可以在所委託被裝飾者的行為之前與/或之後,加上自己的行為。
5)、物件可以在任何時候被裝飾。
4、工廠方法、抽象工廠
工廠方法模式
定義了一個建立物件的視窗,但由子類決定要例項化的類是哪一個。工廠方法讓類把例項化推遲到了子類。所謂“決定”,並不是模式允許子類本身在執行時做決定,而是指在編寫建立者類時,不需要知道實際建立的產品是哪一個。
抽象工廠魔術
提供了一個介面,用於建立相關或依賴物件的家族,而不需要明確指定具體類。允許客戶使用抽象的介面來建立一組相關的產品,而不需要指定實際產出的具體產品是什麼。
5、單例模式
單例模式確保一個類只有一個實力,並提供一個全域性訪問者。
例:
public class Singleton {
private violatile static Singleton instance ;
private Singleton ( ) {
}
public static Singleton getInstance ( ) {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton( );
}
}
}
return instance;
}
}
6、命令模式
將“請求”封裝成物件,以便使用不同的請求、佇列或者日誌來引數化其他物件,命令模式也支援可撤銷的操作。
一個命令物件通過在特定的接收者上繫結一組動作來封裝一個請求。要達到這一點,命令物件將動作和接收者包進
物件中,這個物件只會暴露“execute( )”方法,當此方法被呼叫的時候,接收者就會執行這些動作。
7、介面卡模式
將一個類的介面,轉換成客戶期望的另一個介面,介面卡可以讓原本介面不相容的類合作無間。
物件介面卡:採用組合的方式
類介面卡:採用繼承的方式,需要多重繼承
8、外觀模式
提供了一個統一的介面,用來訪問子系統中的一群介面。外觀模式定義了一個高層介面,讓子系統更容易使用。
9、模板方法模式
在一個方法中定義了一個演算法的骨架,而將一些步驟延遲到子類中。模板方法使得子類在不改變演算法結構的情況下,重新定義演算法中的某些步驟。
鉤子:一種被宣告在抽象類的方法,但只有空的或預設的實現。鉤子的存在,可以讓子類有能力對演算法的不同點進行掛鉤,要不要掛鉤,由子類決定
10、迭代器模式
提供一種方法順序訪問一個聚和物件中的各個元素,而又不暴露其內部表示。
把遊走的任務放在迭代器上,而不是聚合上。這樣簡化了聚合的介面和實現,也讓責任各得其所。
11、組合模式
允許將物件組合成樹形結構來表現“整體/部分”層次結構。組合讓客戶以一致的方式處理個別對象及物件組合
12、狀態模式
允許物件在內部狀態改變時改變它的行為,物件看起來好像修改了它的類
1)、這個模式將狀態封裝成獨立的類,並將動作委託到代表當前物件狀態的物件,行為會隨著內部狀態而改變
2)、使用組合通過簡單引用不同的狀態物件來造成類改變的假象
13、代理模式
為另一個物件提供一個替身或佔位符以控制對這個物件的訪問
使用代理模式建立代表物件,讓代表物件控制某物件的訪問,被代理的物件可以是遠端的物件、建立開銷大的物件或需要安全控制的物件