終于啃完了《Head First design patterns》,順便把用Google筆記本所做的筆記貼出來記錄下~~
OO基礎
抽象, 封裝,多型,繼承
OO原則
1,封裝變化
2,多用組合,少用繼承
3,針對接口編程,不針對實現編程
4,為交互對象之間的松耦合設計而努力
5,為擴展開放,對修改關閉
6,依賴倒置原則(Dependency Inversion Principle)
7,最少知識原則(Least Knowledge),只和你的密友談話。
8,好萊塢原則:別調用我們,我們會調用你。
9,單一責任原則:一個類應該只有以一個引起變化的原因。
1,封裝變化--策略模式(封裝不同的算法--鴨子示例)2,多用組合,少用繼承--策略模式(組合算法--鴨子示例)3,針對接口編程,不針對實現編程4,為交互對象之間的松耦合設計而努力--觀察者模式(出版者/訂閱者--天氣預報與布告板示例)5,對擴展開放,對修改關閉--裝飾者模式(咖啡與調料示例,java的IO庫示例)6,要依賴抽象,不要依賴具體類。--工廠方法模式(pizza店與pizza示例)--抽象工廠模式(pizza與原料示例)7,最少知識原則--外觀模式(家庭影院示例)8,好萊塢原則:別調用我們,我們會調用你在好萊塢原則下,我們允許底層組件將自己掛鉤到系統上,但是高層組件會決定什么時候和怎樣使用這些低層組件。換句話說,高層組件對待低層組件的方式是“別調用我們,我們會調用你”--模板方法模式(泡咖啡和泡茶示例)9,單一責任原則-迭代器模式(不同的菜單實現與女招待:ArrayList與數組)
設計模式
第一章 Strategy-策略模式
策略模式:定義算法族,分別封裝起來,讓他們之間可以互相替換,此模式讓算法的變化獨立于使用算法的客戶。
第二章 Observer-觀察者模式
觀察者模式:定義了對象之間的一對多依賴,這樣一來,當一個對象改變狀態時,它的所有依賴者都會受到通知并自動更新。
第三章 裝飾者模式
裝飾者模式定義:動態地將責任附加到對象上,若要擴展功能,裝飾者提供了比繼承更有彈性的替代方案。
示例:starbuzz 星巴克咖啡調料價格
設計原則:類應該對擴展開放,對修改關閉。
解釋:
1,裝飾者和被裝飾者對象有相同的超類型;
2,既然裝飾者和被裝飾者對象有相同的超類型,所以在任何需要原始對象(被包裝的)的場合,可以用裝飾過的對象替代它。
3,裝飾者可以在所委托被裝飾者的行為之前與/或之后,加上自己的行為,已達到特定的目的。
4,對象可以在任何時候被裝飾,所以可以在運行時動態地,不限量地用你喜歡的裝飾者來裝飾對象。
要點:
--組合和委托可用于在運動時動態地加上新的行為;
--除了繼承,裝飾者模式也可以讓我們擴展行為;
--裝飾者模式意味著一群裝飾者類,這些類用來包裝具體組件;
--裝飾者類反映出被裝飾的組件類型(事實上,他們具有相同的類型,都經過接口或繼承實現)
--你可以用無數個裝飾者包裝一個組件;
--裝飾者一般對組件的客戶是透明的,除非客戶程序依賴于組件的具體類型;
--裝飾者會導致設計中出現許多小對象,如果過度使用,會讓程序變得很復雜。
第四章 Factory Method-工廠方法模式 與Abstact Factory Method -抽象工廠模式
工廠方法模式定義了一個創建對象的接口,但有子類決定要實例化的類似哪一個。工廠方法讓類把實例化推遲到子類。
抽象工廠模式提供一個接口,用于創建相關或依賴對象的家族,而不需要明確指定具體類。
要點:
-所有的工廠都是用來封裝對象的創建。
-簡單工廠,雖然不是真正的設計模式,但仍不失為一個簡單的方法,可以將客戶程序從具體類解耦。
-工廠方法使用繼承:把對象的創建委托給子類,子類實現工廠方法來創建對象。
-抽象工廠使用對象組合:對象的創建被實現在工廠接口所暴露出來的方法中。
-所有工廠模式都通過減少應用程序與具體類之間的依賴性促進松耦合。
-工廠方法允許類將實例化延遲到子類進行。
抽象工廠創建相關的對象家族,而不需要依賴他們的具體類。
-依賴倒置原則,指導我們避免依賴具體類型,而要 盡量依賴抽象。
-工廠是很有威力的技巧,幫助我們針對抽象編程,而不要針對具體類編程。
第五章 Singleton- 單件模式
單件模式-確保一個類只有一個實例,并提供一個全局訪問點。
第六章 命令模式
命令模式將請求封裝成對象,這可以讓你使用不同的請求,隊列,或者日志請求來參數化其他對象。命令模式也可以支持撤銷操作。
示例:遙控器
第七章 Adapter-適配器模式和Facade-外觀模式
適配器模式將一個類的接口,轉換成客戶期望的另一個接口。適配器讓原本接口不兼容的類可以合作無間。
有兩種分類:類適配器和對象適配器。
適配器模式示例:火雞變鴨子,JDK的迭代器
外觀模式示例:家庭影院
第八章 模板方法模式
模板方法模式在一個方法(稱為模板方法)中定義了一個算法的骨架,而將一些步驟延遲到子類中。模板方法使得子類可以在不改變算法結構的情況下,重新定義算法中的某些步驟。
鉤子(hook)是一種被聲明在抽象類中的方法,但只有空的或者默認的實現。鉤子的存在可以讓子類有能力對算法的不同點進行掛鉤,要不要掛鉤,由子類自行決定。
示例:泡咖啡和泡茶
要點:
-模板方法定義了算法的步驟,把這些步驟的實現延遲到子類。
-模板方法模式為我們提供了一種代碼復用的重要技巧。
-模板方法的抽象類可以定義具體方法,抽象方法和鉤子。
-抽象方法由子類實現。
-鉤子是一種方法,它在抽象類中不做事,或者只做默認的事情,子類可以選擇要不要去覆蓋它。
-好萊塢原則告訴我們,將決策權放在高層模塊中, 以便決定如何以及何時調用低層模塊。
-策略模式和模板方法模式都封裝算法,一個用組合,另一個用繼承。
-工廠方法是模板方法的一個特殊版本。
第九章 迭代器(Iterator)與組合模式(Composite)--管理良好的集合
迭代器模式提供一個方法順序訪問一個聚合對象中的各個元素,而又不暴露其內部的表示。
組合模式允許你將對象組合成樹形結構來表現“整體/部分”層次結構。組合能讓客戶以一致的方式處理個別對象以及對象組合。
示例:菜單及其子菜單(樹形結構)
組合模式讓我們能用樹形方式創建對象的結構,樹里面包含了組合以及個別的對象。使用組合結構,我們能把相同的操作應用在組合和個別對象上。換句話說,在大多數情況下,我們可以忽略對象組合和個別對象之間的差別。
何時使用組合模式:當你有數個對象的集合,它們之間有“整體/部分”的關系,并且你想用一致方式對待這些對象時,就可以使用組合模式。
第十章 狀態模式
狀態模式允許對象在內部狀態改變時改變它的行為,對象看起來好像修改了它的類。
狀態模式將狀態封裝成為獨立的類,并將動作委托到代表當前狀態的對象。從客戶的視角來看:如果說你使用的對象能夠完全改變它的行為,那么你會覺得,這個對象實際上是別的類實例化而來的,然而,實際上,你知道我們是使用組合通過簡單引用不同的狀態對象來造成類改變的假象。
策略模式和狀態模式是雙胞胎,他們的類圖完全相同,只是各自的意圖不同。策略模式是圍繞可以互換的算法來創建成功業務的,而狀態模式是通過改變對象內部的狀態來幫助對象控制自己的行為。
以狀態模式而言,我們將一群行為封裝在狀態對象中,context的行為隨時可以委托到那些狀態對象中的一個。隨著時間的流逝,當前狀態在狀態對象集合中游走改變,以反映出context內部的狀態,因此,context的行為也會跟著改變。但是context的客戶對于狀態對象了解不多,甚至根本是渾然不覺。
狀態類會使設計中類的數目大量增加。
第十一章 代理模式(proxy)
代理模式為另一個對象提供一個替身或占位符以控制對這個對象的訪問。
使用代理模式創建代表(Representative)對象,讓代表對象控制某對象的訪問,被代理的對象可以是遠程的對象,創建開銷大的對象或需要安全控制的對象。
-遠程代理控制訪問遠程對象(java中的RMI)
-虛擬代理控制訪問創建開銷大的資源(遠程圖片顯示)
-保護代理基于權限控制對資源的訪問
第十二章 復合模式(Compound)
-模式通常被一起使用,并被組合在同一個設計解決方案中。
-復合模式在一個解決方案中結合兩個或多個模式,以解決一般或重復發生的問題。
示例:鴨子與鵝(適配器,迭代模式,觀察者,抽象工廠,策略模式)
MVC:模型視圖控制器(策略,觀察者,組合模式)
第十三章 真實生活中的模式
-讓設計模式自然而然地出現在你的設計中,而不是為了使用而使用。
-設計模式并非僵化的教條,你可以依據自己的需要采用或調整。
-總是使用滿足需要的最簡單解決方案,不管它用不用模式。
-學習設計模式的類目,可以幫你自己熟悉這些模式以及它們之間的關系。
模式的分類:
創建型,結構型與行為模式
創建型模式:抽象工廠模式,生成器模式,工廠方法模式,原型模式,單件模式
結構型模式: 適配器模式,橋接模式,組合模式,裝飾者模式,外觀模式,享元模式,代理模式
行為模式:職責鏈模式,命令模式,解釋器模式,迭代器模式,中介者模式,備忘錄模式,觀察者模式,狀態模式,策略模式,模板方法模式,訪問者模式
類模式和對象模式
類模式:模板方法模式(Template method),工廠方法模式(Factory method),適配器模式(Adapter),解釋器模式(Interpreter)
對象模式:組合模式(),訪問者模式,外觀模式,代理模式,策略模式,橋接模式,享元模式,抽象工廠模式,單件模式,迭代器模式,命令模式,備忘錄模式,觀察者模式,職責鏈模式,中介者模式,原型模式,生成器模式
總結:
裝飾者模式:包裝一個對象,以提供新的行為。
適配器模式:封裝對象,并提供不同的接口。
模板方法模式:由子類決定如何實現一個算法中的步驟。
工廠方法模式:由子類決定要創建的具體類似哪一個。
單件模式:確保有且只有一個對象被創建。
策略模式:封裝可以互換的行為,并使用委托來決定要使用哪一個。
組合模式:客戶用一致的方式處理對象集合和單個對象。
狀態模式:封裝了基于狀態的行為,并使用委托在行為之間切換。
迭代器模式:在對象的集合之中游走,而不是暴露集合的實現。
外觀模式:簡化一群類的接口。
裝飾者模式:包裝一個對象,以提供新的行為。
抽象工廠方法:允許客戶創建對象的家族,而無需指定他們的具體類。
觀察者模式:讓對象能夠在狀態改變時被通知。
代理模式:包裝對象,以控制對此對象的訪問。
命令模式:封裝請求成為對象。
附錄A 剩余的模式
橋接模式(Bridge)
使用橋接模式不只改變你的實現,也改變你的抽象。橋接模式通過將實現和抽象放在兩個不同的類層次中而使它們可以獨立改變。
橋接的優點:
-將實現予以解耦,讓它和界面之間不再永久綁定。
-抽象和實現可以獨立擴展,不會影響到對方。
-對于“具體的抽象類”所做的改變,不會影響到客戶。
橋接的用途和缺點:
-適合使用在需要跨越多個平臺的圖形和窗口系統上。
-當需要用不同的方法改變接口和實現時,你會發現橋接模式很好用。
-橋接模式的缺點是增加了復雜度。
示例:控制器與界面各自的抽象
生成器模式(Builder)
-使用生成器模式封裝一個產品的構造過程,并允許按步驟構造。
生成器的優點:
-將一個復雜對象的創建過程封裝起來。
-允許對象通過多個步驟來創建,并且可以改變過程(這和只有一個步驟的工程模式不同)。
-向客戶隱藏產品內部的實現。
-產品的實現可以被替換,因為客戶只看到一個抽象的接口。
生成器的用途和缺點:
-經常被用來創建組合結構
-與工廠模式相比,采用生成器模式創建對象的客戶,需要具備更多的領域知識。
示例:度假計劃
責任鏈模式(Chain of responsibility)
當你想要讓一個以上的對象有機會能夠處理某個請求的時候,就使用責任鏈模式。
責任鏈模式的優點:
-將請求的發送者和接受者解耦
-可以簡化你的對象,因為它不需要知道鏈的結構
-通過改變鏈內的成員或調動它們的次序,允許你動態地新增或者刪除責任
責任鏈的用途與缺點:
-經常被使用在窗口系統中,處理鼠標和鍵盤之類的事件
-并不保證請求一定會被執行;如果沒有任何對象處理它的話,它可能會落到鏈尾之外(這可以是優點也可以是缺點)
-可能不容易觀察運行時的特征,有礙于除錯
示例:不同郵件(垃圾郵件,Fans郵件,客服郵件,業務郵件等)的處理
享元模式(Flyweight)
如想讓某個類的一個實例能用來提供許多“虛擬實例”,就是用享元模式
享元模式的優點:
-減少運行時對象實例的個數,節省內存
-將許多“虛擬對象”的狀態集中管理
享元模式的用途與缺點:
-當一個類有許多的實例,而這些實例能被同一方法控制的時候,我們就可以使用享元模式
-缺點:一旦你實現了它,那么單個的邏輯實例將無法擁有獨立而不同的處理
享元模式
示例:景觀設計中的點綴樹的顯示(只一個樹實例,共享位置年輪信息)
解釋器模式(Intepreter)
使用解釋器模式為語言創建解釋器
解釋器的優點:
-將每一個語法規則表示成一個類,方便于實現語言
-將每一個語法規則表示成一個類,方便于實現語言
-因為語法由許多類表示,所以你可以輕易地改變或擴展此語言
-通過在類結構中加入新的方法,可以在解釋的同時增加新的行為,例如打印格式的美化或者進行復雜的程序驗證
解釋器的用途與缺點:
-當你需要實現一個簡單的語言時,使用解釋器
-當你有一個簡單的語法,而且簡單比效率更重要時,使用解釋器
-可以處理腳本語言和編程語言
-當語言規則的數碼太大時,這個模式可能會變得相當繁雜,在這種情況下,使用解釋器/編譯器的產生器可能更合適
示例:Duck pond控制鴨子的語言解釋器
中介者模式(Mediator)
使用中介者模式來集中相關對象之間復雜的溝通和控制方式。每個對象都會在自己的狀態改變時,告訴中介者,每個對象都會對中介者所發出的請求作出反應。中介者內包含了整個系統的控制邏輯。當某個對象需要一個新的規則時,或者是一個新的對象被加入系統內,其所有需要用到的邏輯也都被加入中介者內。
中介者模式的優點:
-通過將對象彼此解耦,可以增加對象的復用性
-通過將控制邏輯集中,可以簡化系統維護
-可以讓對象之間所傳遞的消息變得簡單而且大幅減少
中介者模式的用途和缺點:
-中介者模式常常被用來協調相關的GUI組件
-中介者模式的缺點是:如果設計不當,中介者對象本身會變得過于復雜
示例:生活自動機(鬧鈴,煮咖啡,日歷,噴頭)
備忘錄模式(Memento)
當你需要讓對象返回之前的狀態時(例如:undo),就使用備忘錄模式。備忘錄模式有兩個目標:儲存系統關鍵對象的重要狀態;維護關鍵對象的封裝。請不要忘記單一責任原則,不要把保持狀態的工作和關鍵對象混在一起,這樣比較好。這個專門掌握狀態的對象就稱為備忘錄。
備忘錄模式的優點:
-被儲存的狀態放在外面,不要和關鍵對象混在一起,這可以幫助維護內聚
-保持關節對象的數據封裝
-提供了容易實現的恢復能力
備忘錄模式的用途和缺點:
-備忘錄用于儲存狀態
-使用備忘錄的缺點:儲存和恢復狀態的過程可能相當耗時
-在Java系統中,其實可以考慮使用序列化(Serialization)機制儲存系統的狀態
示例:游戲中的存儲進度功能
原型模式(Prototype)
當創建給定類的實例的過程很昂貴或很復雜時,就使用原型模式。原型模式允許你通過使用復制現有的實例來創建新的實例(在Java中,這通常意味著使用clone()方法或者反序列化)。這個模式的重點在于,客戶的代碼在不知道要實例化何種特定類的情況下,可以制造出新的實例。
原型模式的優點:
-向客戶隱藏制造新實例的復雜性
-提供客戶能夠產生未知類型對象的選項
-在某些環境下,復制對象比創建新對象更有效
原型模式的用途和缺點:
-在一個復雜的類層次中,當系統必須從其中的許多類型創建新對象時,可以考慮原型
-缺點:對象的復制有時相當復雜
示例:在游戲中創建各式各樣的怪獸
訪問者模式(Visitor)
當你想要為一個對象的組合增加新的能力,且封裝并不重要時,就使用訪問者模式。
客戶要求訪問者從組合結構中取得信息,新方法可以被加入到訪問者中,而不會影響組合;訪問者需要能夠調用組合類的getState(),而這也正是你能夠加入新方法以讓客戶使用的地方;所有的這些組合類必須做的事情就是加入一個getState()方法,而不必擔心暴露他們自己。
訪問者模式的優點:
-允許你對組合結構加入新的操作,而不需改變結構本身
-想要加入新的操作,相對容易
-訪問者所進行的操作,其代碼是集中在一起的
訪問者模式的用途和缺點:
-當采用訪問者模式的時候,就會打破組合類的封裝
-因為游走的功能牽涉其中,所以對組合結構的改變就更加困難
示例:對鄉村餐廳的菜單添加營養成分,能量顯示