關於設計模式的思想:
1.設計模式的作用,就是幫助我們編寫可復用的類。通過設計,使代碼解耦,響應變化。
2.不要使用具體類來編程,要優先使用抽象類和接口來編程
3.良好的實際模式,可以減少系統的復雜性,提高系統易用性
4.定義抽象類,抽象重要功能(API),把“定義”和“實現”分離開來,從而實現解耦和可復用
關於UML:
1.斜體方式顯示:表示抽象類或者抽象方法
2.下划線方式顯示:表示是靜態類或者靜態方法
3.使用箭頭表示兩個類關系的時候,可以在類名上面加上黑色三角表示關聯關系
4.UML的時序圖(sequence diagram)用來表示程序在工作時其內部方法的調用順序,以及事件的發生順序
5.類圖表示的是“不因時間流逝而發生變化的關系(靜態關系)”,時序圖則相反,表示的是“隨時間發生變化的東西(動態行為)”
理解角色——誰扮演了白雪公主
第1部分 適應設計模式
第一章、Iterator(迭代器)模式

角色:Iterator(迭代器)、ConcreterIterator(具體的迭代器)、Aggregate(集合)、ConcreterLterator(具體的集合)
個人理解:通過ConcreterLterator里實現具體hasNext接口和next接口,來定制化寫集合的遍歷邏輯
好處:使遍歷的實現與使用場景分離出來,遍歷的實現,可以由集合的開發者自定義,而集合的使用者,則只需調用遍歷的接口使用就行。
第二章、Adapter(適配器)模式
1.類適配器模式(使用繼承的適配器)

角色:Target對象(Print)、Adaptee被適配(Banner)、Adapter適配(PrintBanner)、
個人理解:通過實現接口方法(需求)並調用基礎類(實際情況)來實現
使用場景:
1)封裝。測試封裝好的類,為了不破壞原有組件,而直接繼承\調用它
2)復用。為了實現某些接口,而不用重復編寫某些相同代碼,可以使用適配器模式,把老代碼引用過來。
3)繼承。為了能在新版本調用老版本的“組件”,可以通過加適配器,來使老版本的代碼兼容新版本
第2部分 交給子類
第三章、Template method模式

角色:AbstractClass(抽象類)、ConcreteClass(具體類)
個人理解:抽象類復雜聲明抽象方法和模版方法(調用抽象方法)、具體類來實現抽象類里的抽象方法
使用場景:
算法。模版方法是定義算法主邏輯的好地方,一些抽象邏輯可以再根據實際情況來繼承實現。
子類責任:子類具有實現父類抽象方法的責任。因此父類可以要求子類去實現他要求的內容!
第四章、Factory Method模式

角色:Creator(創建者)、Product(產品)、ConcreteCreator(具體的創建者)、ConcreteProduct(具體的產品)
注意:工廠模式是模版模式的典型應用
應用場景:
在需要產生類似功能的實例時使用,如JDBC。調用者不需要關心實例如何產生的。
擴展——父類要求子類生成實例的三種方法:
1.父類指定此方法為抽象方法,這樣,子類就必須實現此方法,否則會編譯報錯(推薦)
2.父類為其實現默認方法,這樣,子類沒有實現父類方法,就調用父類的默認方法
3.父類在此方法中拋出異常,這樣,子類沒有實現此方法的話,執行的時候,就會主動拋出Exception
第3部分 生成實例
第五章、singleton模式

注意:
1)構造函數是private的
2)實例可以在類初始化的時候生成(懶漢模式),也可以在getInstance方法第一次被調用時生成(餓漢模式)。餓漢模式要注意加鎖解決多線程的問題
第六章 Prototype模式

角色:Prototype(原型)、ConcretePrototype(具體的原型)、Client(調用者)
注意:淺拷貝、深拷貝的問題(把model克隆給DTO也采用了克隆,也是采用實例拷貝)
使用場景:
1)需要生成很多個實例,而且實例可能是由同一個類/不同類new出來的
2)生成的實例過程很復雜(如使用鼠標畫的圖),這時與其重現生成的過程,不如直接克隆實例來的方便
3)可以通過封裝成框架代碼,來控制生成實例的規范
擴展1——在設計模式中,出現類名是束縛嗎:
因為設計模式的目標是把代碼作為“組件”而復用,而組件,當然是不能經常修改源碼,一旦設計模式中出現具體的類名,勢必會破壞組件的封裝性,和業務產生耦合。理想的情況是“組件”被打成lib包引入到項目中使用而不需要重新編譯
擴展2——標記接口(marker interface):
Cloneable並沒有定義任何方法,像這種接口,被稱為標記接口,只用來表示可以使用Object類里的clone方法來進行復制
第七章 Builder模式

角色:Builder(建造者)、ConcreteBuilder(具體建造者)、Director(建工)、Client(使用者)
個人理解:建造者模式和模板模式很類似,都是把具體的實現交給實現類來處理,而邏輯,都是由抽象方法先模擬,然后由具體的實現類來根據實際業務實現。他們2者的區別是,模板方法,是通過子類繼承父類,來實現抽象方法。而建造者模式,是通過組合的方式(Director類)。因為組合比基礎更靈活,所以從這點上講,建造模式比模板模式也更靈活。
擴展——誰知道什么:在面向對象的模式設計中,誰知道什么是很重要的一點,正因為好的設計模式屏蔽了很多細節,使組件解耦,開發者在調用組件的時候,才能不需要很多東西。正因為不知道才能夠替換,正因為可以替換,組件才具有高價值。作為設計人員,我們必須時刻關注這種“可替換性”。
第八章 Abstract Factory 模式

角色:AbstractProduct(抽象產品)、AbstractFactory(抽象工廠)、client(委托者)、ConcreteProduct(具體產品)、ConcreteFactory(具體工廠)
優點:易於增加工廠
缺點:難以增加零件
個人理解:抽象工廠模式和工廠模式(還有個簡單工廠模式)類似,但是抽象工廠模式是在工廠模式上面又抽象了一層。在工廠級別就抽象出來了,就可以從實現具體產品,轉變成實現哪類具體的產品。如果只生產某些具體的產品,可以用工廠模式,但如果是要區分生產某些類的產品,則應該用抽象工廠方法
擴展——JAVA生成實例的幾種方法:
1)new
2)clone
3)newInstance:Object.getClass().newInstance()
第4部分 分開考慮
第9章 Bridge模式
類的功能層次結構:父類具有基本功能,在子類中增加新的功能
類的實現層次結構:父類通過聲明抽象方法來定義接口,子類通過實現具體方法來實現接口

角色:Abstraction(抽象化)、RefinedAbstraction(改善后的抽象化,增加了新功能)、Implementor(實現類)、ConcreteImplmentor(具體實現類)
擴展——繼承是強關聯、委托是弱關聯(Bridge模式中,RefinedAbstraction是繼承關系、Implementor是委托關系)
優點:把類的功能層次結構和類的實現層次結構分離開了,這樣有利於它們獨立的擴展
舉例:不同操作系統上,實現一個程序。程序可以不斷擴展,實現可以不斷增加
第10章 strategy模式

角色:Strategy(策略)、ConcreteStrategy(具體策略)、Context(上下文)
要點:在上下文中使用策略時,使用委托這種弱關系可以方便替換算法
舉例:算法、根據具體業務狀態選擇不同策略(程序運行時)
第5部分 一致性
第11章 Composite模式
簡介: 能夠是容器和內容具有一致性,創造出地遞歸結構的模式

角色:Leaf(樹葉,不能放入對象)、Composite(復合物,容器,可以放入對象)、Component(父類,抽象類)、Client(使用者)
使用場景:文件系統、聯合測試、窗口、宏命令,其它一切樹形數據結構
第12章Decorator模式

角色:Component(被裝飾物、核心角色、抽象類)、ConcreteComponent(具體的被裝飾物)、Decorator(裝飾物、抽象類)、ConcreteDecorator(具體的裝飾物)
核心思想:
1)接口的透明性。裝飾物和被裝飾物,具有統一的接口(得益於他們都繼承同一個抽象類)
2)遞歸。和組合模式一樣,裝飾模式也是遞歸結構
3)使用委托,利用遞歸調用,動態的增加功能
應用舉例:java.IO new xxxReader( new BufferReader( new InputStreamReader(xxx) ) )
擴展:一致性
1)繼承:父類和子類一致性
2)委托:自己和被委托的對象保持一致性
3)實現:不同實現者之間保持一致性
第6部分
第13章 Visitor模式

角色:Visitor(訪問者,抽象類)、ConcreteVisitor(具體的訪問者,實現visit接口)、Element(訪問對象、抽象類)、ConcreteElement(具體的訪問對象)、ObjectStructure(對象結構,遍歷Element,處理Element角色的集合)
該模式的特點:
1)可以很方便的增加ConcreteVisitor,難以增加ConcreteElement。因為具體的邏輯被交給了ConcreteVisitor,所以修改邏輯完全不需要改ConcreteElement。
2)Visitor和Element有雙重分發:visitor.visit(element)、element.accept(visitor)。借助這種互相調用的關系,加上遞歸調用,可以把邏輯都遞歸匯總到ConcreteVisitor的visit方法中。
第14章 Chain of Responsibility
核心思想:將許多對象組成一條職責鏈,然后按照它們在職責鏈上的順序一個一個地找出到底應該誰來負責處理。

角色:Handle(處理者,抽象類)、ConcreteHandler(具體的處理者)、Client(請求者)
個人理解:核心是Handle類,里面使用模板方法定義好了調用鏈的邏輯,然后通過遞歸調用下一個處理人。其它ConcreteHandler只負責定義各自的業務處理邏輯,然后等待被調用就行
優點:
1)弱化了發送請求人和處理請求人之間的關系,發送請求人不需要知道“下一個處理人是誰”。
2)可以動態的改變責任鏈:因為處理者可以通過委托“推卸責任”,從而使自己只處理應該自己處理的任務(單一職責原則)
擴展:責任鏈模式雖然靈活和解耦,但是會降低效率,因為需要在鏈路上都走一遍。所以如果需要非常快的處理的時候,不應該使用此模式(類似Arrylist和LinkList那樣,鏈表結構在查詢的時候,速度是比較慢的)
第7部分 簡單化
第15章 Facade模式

角色:facde(窗口)、classX(構成系統的其它角色)、client(業務場景,調用者)
重點:對外的API(接口)變少了,client只需要關注facade的public接口,而不用關心它下面的那些復雜邏輯
優點:封裝性好
使用舉例:MVC中的controller層,框架代碼里的對外接口
第16章 Mediator模式

角色:Mediator(仲裁者、中介者、接口)、ConcreteMediator(具體的仲裁者、實現類)、Colleague(同事、抽象)、ConcreteColleague(具體的同事、實現類)
中心思想:把原本分散在各個colleague的(會互相影響其它colleague的)業務邏輯,集中化到Mediator去處理,通過觸發Mediator的onChanger接口,監聽變化。
優點:
1)把復雜的互相關聯的業務邏輯,集中化管來起來。避免業務邏輯分散在各個colleague類中
2)colleague類可以復用和擴展
應用場景(個人猜測):服務注冊、消息總線
第8部分 管理狀體
第17章Observer(觀察者)模式

角色:Subject(觀察對象,抽象類)、ConcreteSuject(具體的觀察者)、Observer(觀察者)、ConcreteObserver(具體的觀察者)
中心思想:觀察對象,通過“注冊”多個觀察者,來消息通知(通過update接口)各個觀察者。它的有一個延伸,叫訂閱發布者模式。
思路拓展:設計模式的一個常用手段,就是利用抽象類,抽象具體類的關鍵方法。然后將實例作為參數傳遞至類中,或者在類的字段中保存實例時,不實用具體類型,而是使用抽象類型和接口。
這樣的實現方式可以幫助我們輕松替換具體類,實現了解構。
第18章 Memento(備忘錄)模式

角色:Originator(生成者,被保存的對象)、Memento(紀念品,存檔)、Caretaker(責任人,調用者)
中心思想:Caretaker將Originator的狀態,保存為Memento
優點:職責分擔,caretaker只負責執行保存動作,Orginator負責保存的邏輯,Memento負責決定保存的信息(提供保存的接口)
擴展——寬接口、窄接口:根據職責的不同,限制不同接口的訪問權限,只暴露自己必要的信息
應用場景:復制/粘貼、游戲存檔
第19章 State 模式

角色:State(狀態,抽象類)、ConcreteState(具體狀態、實現類)、Context(狀況,上下文)
中心思想:Contenxt調用State類,來根據不同情況處理不同邏輯。具體的處理邏輯,放在State的子類(ConcreteState)里來實現
核心思想:依賴於狀體的處理,該模式下,通過定義抽象類(state)和具體的實現類(ConcreteState),可以實現“狀態不同處理也不同”
第9部分 避免浪費
第20章 Flyweight(享元)模式

角色:Flyweight(共享類,輕量級)、FlyweightFactory(共享類工程)、Client(調用者)
中心思想:FlywightFactory通過pool(共享池)來保存共享Flyweight(單例模式),使得Flyweight可以被復用
優點:可以批量修改共享類,可以減少資源開銷
應用舉例:spring bean(個人猜測)
第21章 proxy模式

角色:subject(主體,抽象類)、proxy(代理人,只有在自己不能處理的時候,才交給RealSubject去處理)、RealSubject(實際的主體、在代理人無法處理時出場)、client(調用者,可以隨意調用proxy或realSubject)
中心思想:通過設置統一的接口(subject),試client可以不直接調用realSuject,而是通過調用proxy來實現業務功能。而在proxy里,相當於做了一層緩存,只有才必要時才調用realsubject
優點:
1)划分了proxy和realSubject兩個角色,使得他們互相不影響,client可以選擇單獨使用realSubject或者使用代理來做,而不需要改變業務邏輯
2)因為proxy和realSubject都實現了subject接口所以client可以不必在意,使用的是哪個具體類去實現邏輯。因此proxy可以說具有透明性,透過它就像可以直接看到realSubject一樣
應用舉例:http代理、緩存
第10部分 用類來表現
第22章 command(命令、事件)模式

第23章 Interpreter模式

角色:AbstractExpression(抽象表達式)、TerminalExpression(終結表達式、具體實現)、NonterminalExpression(非終結表達式、具體實現)、Context(上下文,被解析對象)、Clinet(調用者)
個人理解:通過抽象接口,統一解析的方法,然后遞歸調用具體的解析類直到終結表達式
