【转】设计模式总结
http://www.cnblogs.com/chenssy/p/3357683.html
????? 從七月份開始一直到九月底才看完設(shè)計模式,在這個過程中我不敢說我已經(jīng)掌握了那本書里面的內(nèi)容,或者說1/5,沒能力說也沒有資格說。但是結(jié)果不重要,重要的是這個過程我的收獲!主要包括如下幾個方面:
????? 1、認(rèn)識了這么多設(shè)計模式。剛剛接觸java沒多久就在學(xué)長那里聽過設(shè)計模式的大名,但是由于能力有限,一直不敢觸碰。而今有幸將其都認(rèn)識了。
????? 2、開始有設(shè)計的理論了。在接觸設(shè)計模式之前沒有怎么想過設(shè)計方面東東,看到問題就立馬動手解決,沒有想到怎么樣來設(shè)計更好,如何來是這塊更加優(yōu)化、漂亮。
????? 3、開始考慮系統(tǒng)的可擴(kuò)展性了。
????? 4、在遇到問題后開始想有那個設(shè)計模式會適用這個場景。
????? 5、對面向?qū)ο笥辛烁钜徊降牧私狻?/p>
????? 鄙人天資不聰慧,既不是聰明人,更不是那種天才,所有頓悟有限!!!閑話過多,先看如下兩幅圖片
設(shè)計模式之間的關(guān)系:
????? 設(shè)計模式總概況:
一、設(shè)計原則
1、單一職責(zé)原則
????? 一個類,只有一個引起它變化的原因。應(yīng)該只有一個職責(zé)。每一個職責(zé)都是變化的一個軸線,如果一個類有一個以上的職責(zé),這些職責(zé)就耦合在了一起。這會導(dǎo)致脆弱的設(shè)計。當(dāng)一個職責(zé)發(fā)生變化時,可能會影響其它的職責(zé)。另外,多個職責(zé)耦合在一起,會影響復(fù)用性。例如:要實(shí)現(xiàn)邏輯和界面的分離。from:百度百科
2、開閉原則(Open Close Principle)
????? 開閉原則就是說對擴(kuò)展開放,對修改關(guān)閉。在程序需要進(jìn)行拓展的時候,不能去修改原有的代碼,實(shí)現(xiàn)一個熱插拔的效果。所以一句話概括就是:為了使程序的擴(kuò)展性好,易于維護(hù)和升級。想要達(dá)到這樣的效果,我們需要使用接口和抽象類,后面的具體設(shè)計中我們會提到這點(diǎn)。
3、里氏代換原則(Liskov Substitution Principle)
????? 里氏代換原則(Liskov Substitution Principle LSP)面向?qū)ο笤O(shè)計的基本原則之一。 里氏代換原則中說,任何基類可以出現(xiàn)的地方,子類一定可以出現(xiàn)。 LSP是繼承復(fù)用的基石,只有當(dāng)衍生類可以替換掉基類,軟件單位的功能不受到影響時,基類才能真正被復(fù)用,而衍生類也能夠在基類的基礎(chǔ)上增加新的行為。里氏代換原則是對“開-閉”原則的補(bǔ)充。實(shí)現(xiàn)“開-閉”原則的關(guān)鍵步驟就是抽象化。而基類與子類的繼承關(guān)系就是抽象化的具體實(shí)現(xiàn),所以里氏代換原則是對實(shí)現(xiàn)抽象化的具體步驟的規(guī)范。from:百度百科
4、依賴倒轉(zhuǎn)原則(Dependence Inversion Principle)
????? 所謂依賴倒置原則(Dependence Inversion Principle)就是要依賴于抽象,不要依賴于具體。簡單的說就是要求對抽象進(jìn)行編程,不要對實(shí)現(xiàn)進(jìn)行編程,這樣就降低了客戶與實(shí)現(xiàn)模塊間的耦合。
????? 實(shí)現(xiàn)開閉原則的關(guān)鍵是抽象化,并且從抽象化導(dǎo)出具體化實(shí)現(xiàn),如果說開閉原則是面向?qū)ο笤O(shè)計的目標(biāo)的話,那么依賴倒轉(zhuǎn)原則就是面向?qū)ο笤O(shè)計的主要手段。 from:百度百科
5、接口隔離原則(Interface Segregation Principle)
????? 這個原則的意思是:使用多個隔離的接口,比使用單個接口要好。還是一個降低類之間的耦合度的意思,從這兒我們看出,其實(shí)設(shè)計模式就是一個軟件的設(shè)計思想,從大型軟件架構(gòu)出發(fā),為了升級和維護(hù)方便。所以上文中多次出現(xiàn):降低依賴,降低耦合。
6、合成復(fù)用原則(Composite Reuse Principle)
????? 合成復(fù)用原則就是指在一個新的對象里通過關(guān)聯(lián)關(guān)系(包括組合關(guān)系和聚合關(guān)系)來使用一些已有的對象,使之成為新對象的一部分;新對象通過委派調(diào)用已有對象的方法達(dá)到復(fù)用其已有功能的目的。簡言之:要盡量使用組合/聚合關(guān)系,少用繼承。
7、迪米特法則(最少知道原則)(Demeter Principle)
????? 為什么叫最少知道原則,就是說:一個實(shí)體應(yīng)當(dāng)盡量少的與其他實(shí)體之間發(fā)生相互作用,使得系統(tǒng)功能模塊相對獨(dú)立。也就是說一個軟件實(shí)體應(yīng)當(dāng)盡可能少的與其他實(shí)體發(fā)生相互作用。這樣,當(dāng)一個模塊修改時,就會盡量少的影響其他的模塊,擴(kuò)展會相對容易,這是對軟件實(shí)體之間通信的限制,它要求限制軟件實(shí)體之間通信的寬度和深度。
二、創(chuàng)建型模式
????? 在軟件工程中,創(chuàng)建型模式是處理對象創(chuàng)建的設(shè)計模式,試圖根據(jù)實(shí)際情況使用合適的方式創(chuàng)建對象。基本的對象創(chuàng)建方式可能會導(dǎo)致設(shè)計上的問題,或增加設(shè)計的復(fù)雜度。創(chuàng)建型模式通過以某種方式控制對象的創(chuàng)建來解決問題。
????? 創(chuàng)建型模式由兩個主導(dǎo)思想構(gòu)成。一是將系統(tǒng)使用的具體類封裝起來,二是隱藏這些具體類的實(shí)例創(chuàng)建和結(jié)合的方式。
????? 創(chuàng)建型模式又分為對象創(chuàng)建型模式和類創(chuàng)建型模式。對象創(chuàng)建型模式處理對象的創(chuàng)建,類創(chuàng)建型模式處理類的創(chuàng)建。詳細(xì)地說,對象創(chuàng)建型模式把對象創(chuàng)建的一部分推遲到另一個對象中,而類創(chuàng)建型模式將它對象的創(chuàng)建推遲到子類中。
1、抽象工廠模式(Abstract Factory)
????? 所謂抽象工廠模式就是她提供一個接口,用于創(chuàng)建相關(guān)或者依賴對象的家族,而不需要明確指定具體類。他允許客戶端使用抽象的接口來創(chuàng)建一組相關(guān)的產(chǎn)品,而不需要關(guān)系實(shí)際產(chǎn)出的具體產(chǎn)品是什么。這樣一來,客戶就可以從具體的產(chǎn)品中被解耦。它的優(yōu)點(diǎn)是隔離了具體類的生成,使得客戶端不需要知道什么被創(chuàng)建了,而缺點(diǎn)就在于新增新的行為會比較麻煩,因?yàn)楫?dāng)添加一個新的產(chǎn)品對象時,需要更加需要更改接口及其下所有子類。其UML結(jié)構(gòu)圖如下:
????? 參與者:
???????? AbstractFactory:抽象工廠。抽象工廠定義了一個接口,所有的具體工廠都必須實(shí)現(xiàn)此接口,這個接口包含了一組方法用來生產(chǎn)產(chǎn)品。
???????? ConcreteFactory:具體工廠。具體工廠是用于生產(chǎn)不同產(chǎn)品族。要創(chuàng)建一個產(chǎn)品,客戶只需要使用其中一個工廠完全不需要實(shí)例化任何產(chǎn)品對象。
???????? AbstractProduct:抽象產(chǎn)品。這是一個產(chǎn)品家族,每一個具體工廠都能夠生產(chǎn)一整組產(chǎn)品。
???????? Product:具體產(chǎn)品。
2、建造者模式(Builder)
??????對于建造者模式而已,它主要是將一個復(fù)雜對象的構(gòu)建與表示分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示。適用于那些產(chǎn)品對象的內(nèi)部結(jié)構(gòu)比較復(fù)雜。
????? 建造者模式將復(fù)雜產(chǎn)品的構(gòu)建過程封裝分解在不同的方法中,使得創(chuàng)建過程非常清晰,能夠讓我們更加精確的控制復(fù)雜產(chǎn)品對象的創(chuàng)建過程,同時它隔離了復(fù)雜產(chǎn)品對象的創(chuàng)建和使用,使得相同的創(chuàng)建過程能夠創(chuàng)建不同的產(chǎn)品。但是如果某個產(chǎn)品的內(nèi)部結(jié)構(gòu)過于復(fù)雜,將會導(dǎo)致整個系統(tǒng)變得非常龐大,不利于控制,同時若幾個產(chǎn)品之間存在較大的差異,則不適用建造者模式,畢竟這個世界上存在相同點(diǎn)大的兩個產(chǎn)品并不是很多,所以它的使用范圍有限。其UML結(jié)構(gòu)圖:
???????參與者:
???????? Builder:抽象建造者。它聲明為創(chuàng)建一個Product對象的各個部件指定的抽象接口。?
???????? ConcreteBuilder:具體建造者。實(shí)現(xiàn)抽象接口,構(gòu)建和裝配各個部件。?
???????? Director:指揮者。構(gòu)建一個使用Builder接口的對象。它主要是用于創(chuàng)建一個復(fù)雜的對象,它主要有兩個作用,一是:隔離了客戶與對象的生產(chǎn)過程,二是:負(fù)責(zé)控制產(chǎn)品對象的生產(chǎn)過程。?
???????? Product:產(chǎn)品角色。一個具體的產(chǎn)品對象。
3、工廠方法模式(Factory Method)
????? 作為抽象工廠模式的孿生兄弟,工廠方法模式定義了一個創(chuàng)建對象的接口,但由子類決定要實(shí)例化的類是哪一個,也就是說工廠方法模式讓實(shí)例化推遲到子類。
????? 工廠方法模式非常符合“開閉原則”,當(dāng)需要增加一個新的產(chǎn)品時,我們只需要增加一個具體的產(chǎn)品類和與之對應(yīng)的具體工廠即可,無須修改原有系統(tǒng)。同時在工廠方法模式中用戶只需要知道生產(chǎn)產(chǎn)品的具體工廠即可,無須關(guān)系產(chǎn)品的創(chuàng)建過程,甚至連具體的產(chǎn)品類名稱都不需要知道。雖然他很好的符合了“開閉原則”,但是由于每新增一個新產(chǎn)品時就需要增加兩個類,這樣勢必會導(dǎo)致系統(tǒng)的復(fù)雜度增加。其UML結(jié)構(gòu)圖:
?
????? 參與者:
????????? Product:抽象產(chǎn)品。所有的產(chǎn)品必須實(shí)現(xiàn)這個共同的接口,這樣一來,使用這些產(chǎn)品的類既可以引用這個接口。而不是具體類 。
???????? ConcreteProduct:具體產(chǎn)品。
???????? Creator:抽象工廠。它實(shí)現(xiàn)了所有操縱產(chǎn)品的方法,但不實(shí)現(xiàn)工廠方法。Creator所有的子類都必須要實(shí)現(xiàn)factoryMethod()方法。
???????? ConcreteCreator:具體工廠。制造產(chǎn)品的實(shí)際工廠。它負(fù)責(zé)創(chuàng)建一個或者多個具體產(chǎn)品,只有ConcreteCreator類知道如何創(chuàng)建這些產(chǎn)品。
4、原型模式(Prototype)
????? 在我們應(yīng)用程序可能有某些對象的結(jié)構(gòu)比較復(fù)雜,但是我們又需要頻繁的使用它們,如果這個時候我們來不斷的新建這個對象勢必會大大損耗系統(tǒng)內(nèi)存的,這個時候我們需要使用原型模式來對這個結(jié)構(gòu)復(fù)雜又要頻繁使用的對象進(jìn)行克隆。所以原型模式就是用原型實(shí)例指定創(chuàng)建對象的種類,并且通過復(fù)制這些原型創(chuàng)建新的對象。
????? 它主要應(yīng)用與那些創(chuàng)建新對象的成本過大時。它的主要優(yōu)點(diǎn)就是簡化了新對象的創(chuàng)建過程,提高了效率,同時原型模式提供了簡化的創(chuàng)建結(jié)構(gòu)。UML結(jié)構(gòu)圖:
?
?????? 參與者:
????????? Prototype:抽象原型類。聲明克隆自身的接口。?
????????? ConcretePrototype:具體原型類。實(shí)現(xiàn)克隆的具體操作。?
????????? Client:客戶類。讓一個原型克隆自身,從而獲得一個新的對象。
5、單例模式(Singleton)
????? 單例模式,從字面上看就是一個實(shí)例的意思。所以它的定義就是確保某一個類只有一個實(shí)例,并且提供一個全局訪問點(diǎn)。
????? 單例模式具備如下幾個特點(diǎn):
????????? 1、只有一個實(shí)例。
????????? 2、能夠自我實(shí)例化。
????????? 3、提供全局訪問點(diǎn)。
????? 所以說當(dāng)系統(tǒng)中只需要一個實(shí)例對象或者系統(tǒng)中只允許一個公共訪問點(diǎn),除了這個公共訪問點(diǎn)外,不能通過其他訪問點(diǎn)訪問該實(shí)例時,可以使用單例模式。
?????? 單例模式的主要優(yōu)點(diǎn)就是節(jié)約系統(tǒng)資源、提高了系統(tǒng)效率,同時也能夠嚴(yán)格控制客戶對它的訪問。也許就是因?yàn)橄到y(tǒng)中只有一個實(shí)例,這樣就導(dǎo)致了單例類的職責(zé)過重,違背了“單一職責(zé)原則”,同時也沒有抽象類,所以擴(kuò)展起來有一定的困難。其UML結(jié)構(gòu)圖非常簡單,就只有一個類:
?
????? 參與者:
???????? Singleton:單例。
三、結(jié)構(gòu)型模式
????? 結(jié)構(gòu)型模式主要是用于處理類或者對象的組合,它描述了如何來類或者對象更好的組合起來,是從程序的結(jié)構(gòu)上來解決模塊之間的耦合問題。它主要包括適配器模式、橋接模式、組合模式、裝飾模式、外觀模式、享元模式、代理模式這個七個模式。
1、適配器模式(Adapter)
????? 在我們的應(yīng)用程序中我們可能需要將兩個不同接口的類來進(jìn)行通信,在不修改這兩個的前提下我們可能會需要某個中間件來完成這個銜接的過程。這個中間件就是適配器。所謂適配器模式就是將一個類的接口,轉(zhuǎn)換成客戶期望的另一個接口。它可以讓原本兩個不兼容的接口能夠無縫完成對接。
????? 作為中間件的適配器將目標(biāo)類和適配者解耦,增加了類的透明性和可復(fù)用性。
????? 參與者:
???????? Target:目標(biāo)抽象類 。
???????? Adapter:適配器類 。通過在內(nèi)部包裝一個Adaptee,將源接口轉(zhuǎn)成目標(biāo)接口。
???????? Adaptee:適配者類 。需要適配的類。
???????? Client:客戶類。
2、橋接模式(Bridge)
????? 如果說某個系統(tǒng)能夠從多個角度來進(jìn)行分類,且每一種分類都可能會變化,那么我們需要做的就是講這多個角度分離出來,使得他們能獨(dú)立變化,減少他們之間的耦合,這個分離過程就使用了橋接模式。所謂橋接模式就是講抽象部分和實(shí)現(xiàn)部分隔離開來,使得他們能夠獨(dú)立變化。
????? 橋接模式將繼承關(guān)系轉(zhuǎn)化成關(guān)聯(lián)關(guān)系,封裝了變化,完成了解耦,減少了系統(tǒng)中類的數(shù)量,也減少了代碼量。
????? 參與者
???????? Abstraction:抽象類。?
???????? RefinedAbstraction:擴(kuò)充抽象類。?
???????? Implementor:實(shí)現(xiàn)類接口。?
???????? ConcreteImplementor:具體實(shí)現(xiàn)類 。
?
3、組合模式(Composite)
??????組合模式組合多個對象形成樹形結(jié)構(gòu)以表示“整體-部分”的結(jié)構(gòu)層次。它定義了如何將容器對象和葉子對象進(jìn)行遞歸組合,使得客戶在使用的過程中無須進(jìn)行區(qū)分,可以對他們進(jìn)行一致的處理。
????? 在使用組合模式中需要注意一點(diǎn)也是組合模式最關(guān)鍵的地方:葉子對象和組合對象實(shí)現(xiàn)相同的接口。這就是組合模式能夠?qū)⑷~子節(jié)點(diǎn)和對象節(jié)點(diǎn)進(jìn)行一致處理的原因。
????? 雖然組合模式能夠清晰地定義分層次的復(fù)雜對象,也使得增加新構(gòu)件也更容易,但是這樣就導(dǎo)致了系統(tǒng)的設(shè)計變得更加抽象,如果系統(tǒng)的業(yè)務(wù)規(guī)則比較復(fù)雜的話,使用組合模式就有一定的挑戰(zhàn)了。
????? 參與者:
???????? Component :組合中的對象聲明接口,在適當(dāng)?shù)那闆r下,實(shí)現(xiàn)所有類共有接口的默認(rèn)行為。聲明一個接口用于訪問和管理Component子部件。?
???????? Leaf:葉子對象。葉子結(jié)點(diǎn)沒有子結(jié)點(diǎn)。?
???????? Composite:容器對象,定義有枝節(jié)點(diǎn)行為,用來存儲子部件,在Component接口中實(shí)現(xiàn)與子部件有關(guān)操作,如增加(add)和刪除(remove)等。
4、裝飾者模式(Decorator)
????? 我們可以通過繼承和組合的方式來給一個對象添加行為,雖然使用繼承能夠很好擁有父類的行為,但是它存在幾個缺陷:一、對象之間的關(guān)系復(fù)雜的話,系統(tǒng)變得復(fù)雜不利于維護(hù)。二、容易產(chǎn)生“類爆炸”現(xiàn)象。三、是靜態(tài)的。在這里我們可以通過使用裝飾者模式來解決這個問題。
??????裝飾者模式,動態(tài)地將責(zé)任附加到對象上。若要擴(kuò)展功能,裝飾者提供了比繼承更加有彈性的替代方案。雖然裝飾者模式能夠動態(tài)將責(zé)任附加到對象上,但是他會產(chǎn)生許多的細(xì)小對象,增加了系統(tǒng)的復(fù)雜度。
????? 參與者:
???????? Component:?抽象構(gòu)件。是定義一個對象接口,可以給這些對象動態(tài)地添加職責(zé)。
???????? ConcreteComponent:具體構(gòu)件。是定義了一個具體的對象,也可以給這個對象添加一些職責(zé)。
???????? Decorator:?抽象裝飾類。是裝飾抽象類,繼承了Component,從外類來擴(kuò)展Component類的功能,但對于Component來說,是無需知道Decorator存在的。
???????? ConcreteDecorator:具體裝飾類,起到給Component添加職責(zé)的功能。
5、外觀模式(Facade)
????? 我們都知道類與類之間的耦合越低,那么可復(fù)用性就越好,如果兩個類不必彼此通信,那么就不要讓這兩個類發(fā)生直接的相互關(guān)系,如果需要調(diào)用里面的方法,可以通過第三者來轉(zhuǎn)發(fā)調(diào)用。外觀模式非常好的詮釋了這段話。外觀模式提供了一個統(tǒng)一的接口,用來訪問子系統(tǒng)中的一群接口。它讓一個應(yīng)用程序中子系統(tǒng)間的相互依賴關(guān)系減少到了最少,它給子系統(tǒng)提供了一個簡單、單一的屏障,客戶通過這個屏障來與子系統(tǒng)進(jìn)行通信。
????? 通過使用外觀模式,使得客戶對子系統(tǒng)的引用變得簡單了,實(shí)現(xiàn)了客戶與子系統(tǒng)之間的松耦合。但是它違背了“開閉原則”,因?yàn)樵黾有碌淖酉到y(tǒng)可能需要修改外觀類或客戶端的源代碼。
????? 參與者:
???????? Facade:?外觀角色。知道哪些子系統(tǒng)類負(fù)責(zé)處理請求,將客戶的請求代理給適合的子系統(tǒng)處理。
???????? SubSystem:子系統(tǒng)角色。實(shí)現(xiàn)子系統(tǒng)功能,處理Facade對象發(fā)來的請求。
6、享元模式(Flyweight)
????? 在一個系統(tǒng)中對象會使得內(nèi)存占用過多,特別是那些大量重復(fù)的對象,這就是對系統(tǒng)資源的極大浪費(fèi)。享元模式對對象的重用提供了一種解決方案,它使用共享技術(shù)對相同或者相似對象實(shí)現(xiàn)重用。
??????享元模式就是運(yùn)行共享技術(shù)有效地支持大量細(xì)粒度對象的復(fù)用。系統(tǒng)使用少量對象,而且這些都比較相似,狀態(tài)變化小,可以實(shí)現(xiàn)對象的多次復(fù)用。這里有一點(diǎn)要注意:享元模式要求能夠共享的對象必須是細(xì)粒度對象。
????? 享元模式通過共享技術(shù)使得系統(tǒng)中的對象個數(shù)大大減少了,同時享元模式使用了內(nèi)部狀態(tài)和外部狀態(tài),同時外部狀態(tài)相對獨(dú)立,不會影響到內(nèi)部狀態(tài),所以享元模式能夠使得享元對象在不同的環(huán)境下被共享。同時正是分為了內(nèi)部狀態(tài)和外部狀態(tài),享元模式會使得系統(tǒng)變得更加復(fù)雜,同時也會導(dǎo)致讀取外部狀態(tài)所消耗的時間過長。
????? 參與者:
???????? Flyweight:?抽象享元類。所有具體享元類的超類或者接口,通過這個接口,Flyweight可以接受并作用于外部專題。?
???????? ConcreteFlyweight:?具體享元類。指定內(nèi)部狀態(tài),為內(nèi)部狀態(tài)增加存儲空間。?
???????? UnsharedConcreteFlyweight:?非共享具體享元類。指出那些不需要共享的Flyweight子類。?
???????? FlyweightFactory:?享元工廠類。用來創(chuàng)建并管理Flyweight對象,它主要用來確保合理地共享Flyweight,當(dāng)用戶請求一個Flyweight時,FlyweightFactory就會提供一個已經(jīng)創(chuàng)建的Flyweight對象或者新建一個(如果不存在)。
7、代理模式(Proxy)、
??????代理模式就是給一個對象提供一個代理,并由代理對象控制對原對象的引用。它使得客戶不能直接與真正的目標(biāo)對象通信。代理對象是目標(biāo)對象的代表,其他需要與這個目標(biāo)對象打交道的操作都是和這個代理對象在交涉。
????? 代理對象可以在客戶端和目標(biāo)對象之間起到中介的作用,這樣起到了的作用和保護(hù)了目標(biāo)對象的,同時也在一定程度上面減少了系統(tǒng)的耦合度。
????? 參與者:
???????? Subject:?抽象角色。聲明真實(shí)對象和代理對象的共同接口。
???????? Proxy:?代理角色。代理對象與真實(shí)對象實(shí)現(xiàn)相同的接口,所以它能夠在任何時刻都能夠代理真實(shí)對象。代理角色內(nèi)部包含有對真實(shí)對象的引用,所以她可以操作真實(shí)對象,同時也可以附加其他的操作,相當(dāng)于對真實(shí)對象進(jìn)行封裝。
???????? RealSubject:?真實(shí)角色。它代表著真實(shí)對象,是我們最終要引用的對象。
四、行為型模式
????? 行為型模式主要是用于描述類或者對象是怎樣交互和怎樣分配職責(zé)的。它涉及到算法和對象間的職責(zé)分配,不僅描述對象或者類的模式,還描述了他們之間的通信方式,它將你的注意力從控制流轉(zhuǎn)移到了對象間的關(guān)系上來。行為型類模式采用繼承機(jī)制在類間分派行為,而行為型對象模式使用對象復(fù)合而不是繼承。它主要包括如何11中設(shè)計模式:職責(zé)鏈模式、命令模式、解釋器模式、迭代器模式、中介者模式、備忘錄模式、觀察者模式、狀態(tài)模式、策略模式、模板方法模式、訪問者模式。
1、職責(zé)鏈模式(Chain of Responsibility)
?????? 職責(zé)鏈模式描述的請求如何沿著對象所組成的鏈來傳遞的。它將對象組成一條鏈,發(fā)送者將請求發(fā)給鏈的第一個接收者,并且沿著這條鏈傳遞,直到有一個對象來處理它或者直到最后也沒有對象處理而留在鏈末尾端。
????? 避免請求發(fā)送者與接收者耦合在一起,讓多個對象都有可能接收請求,將這些對象連接成一條鏈,并且沿著這條鏈傳遞請求,直到有對象處理它為止,這就是職責(zé)鏈模式。在職責(zé)鏈模式中,使得每一個對象都有可能來處理請求,從而實(shí)現(xiàn)了請求的發(fā)送者和接收者之間的解耦。同時職責(zé)鏈模式簡化了對象的結(jié)構(gòu),它使得每個對象都只需要引用它的后繼者即可,而不必了解整條鏈,這樣既提高了系統(tǒng)的靈活性也使得增加新的請求處理類也比較方便。但是在職責(zé)鏈中我們不能保證所有的請求都能夠被處理,而且不利于觀察運(yùn)行時特征。
????? 參與者:
???????? Handler:?抽象處理者。定義了一個處理請求的方法。所有的處理者都必須實(shí)現(xiàn)該抽象類。?
???????? ConcreteHandler:?具體處理者。處理它所負(fù)責(zé)的請求,同時也可以訪問它的后繼者。如果它能夠處理該請求則處理,否則將請求傳遞到它的后繼者。?
???????? Client:?客戶類。
2、命令模式(Command)
????? 有些時候我們想某個對象發(fā)送一個請求,但是我們并不知道該請求的具體接收者是誰,具體的處理過程是如何的,們只知道在程序運(yùn)行中指定具體的請求接收者即可,對于這樣將請求封裝成對象的我們稱之為命令模式。所以命令模式將請求封裝成對象,以便使用不同的請求、隊(duì)列或者日志來參數(shù)化其他對象。同時命令模式支持可撤銷的操作。
????? 命令模式可以將請求的發(fā)送者和接收者之間實(shí)現(xiàn)完全的解耦,發(fā)送者和接收者之間沒有直接的聯(lián)系,發(fā)送者只需要知道如何發(fā)送請求命令即可,其余的可以一概不管,甚至命令是否成功都無需關(guān)心。同時我們可以非常方便的增加新的命令,但是可能就是因?yàn)榉奖愫蛯φ埱蟮姆庋b就會導(dǎo)致系統(tǒng)中會存在過多的具體命令類。
?????? 參與者:
????????? Command:?抽象命令類。用來聲明執(zhí)行操作的接口。
????????? ConcreteCommand:?具體命令類。將一個接收者對象綁定于一個動作,調(diào)用接收者相應(yīng)的操作,以實(shí)現(xiàn)Excute。
???????? Invoker:?調(diào)用者。要求該命令執(zhí)行這個請求。
???????? Receiver:?接收者。知道如何實(shí)施與執(zhí)行一個請求相關(guān)的操作,任何類都有可能成為一個接收者。
???????? Client:客戶類。
3、解釋器模式(Interpreter)
???????所謂解釋器模式就是定義語言的文法,并且建立一個解釋器來解釋該語言中的句子。解釋器模式描述了如何構(gòu)成一個簡單的語言解釋器,主要應(yīng)用在使用面向?qū)ο笳Z言開發(fā)的編譯器中。它描述了如何為簡單的語言定義一個文法,如何在該語言中表示一個句子,以及如何解釋這些句子。
????? 參與者:
???????? AbstractExpression:?抽象表達(dá)式。聲明一個抽象的解釋操作,該接口為抽象語法樹中所有的節(jié)點(diǎn)共享。
???????? TerminalExpression:?終結(jié)符表達(dá)式。實(shí)現(xiàn)與文法中的終結(jié)符相關(guān)的解釋操作。實(shí)現(xiàn)抽象表達(dá)式中所要求的方法。文法中每一個終結(jié)符都有一個具體的終結(jié)表達(dá)式與之相對應(yīng)。
???????? NonterminalExpression:?非終結(jié)符表達(dá)式。為文法中的非終結(jié)符相關(guān)的解釋操作。
???????? Context:?環(huán)境類。包含解釋器之外的一些全局信息。
???????? Client:?客戶類。
4、迭代器模式(Iterator)
?????對于迭代在編程過程中我們經(jīng)常用到,能夠游走于聚合內(nèi)的每一個元素,同時還可以提供多種不同的遍歷方式,這就是迭代器模式的設(shè)計動機(jī)。在我們實(shí)際的開發(fā)過程中,我們可能會需要根據(jù)不同的需求以不同的方式來遍歷整個對象,但是我們又不希望在聚合對象的抽象接口中充斥著各種不同的遍歷操作,于是我們就希望有某個東西能夠以多種不同的方式來遍歷一個聚合對象,這時迭代器模式出現(xiàn)了。
????? 何為迭代器模式?所謂迭代器模式就是提供一種方法順序訪問一個聚合對象中的各個元素,而不是暴露其內(nèi)部的表示。迭代器模式是將迭代元素的責(zé)任交給迭代器,而不是聚合對象,我們甚至在不需要知道該聚合對象的內(nèi)部結(jié)構(gòu)就可以實(shí)現(xiàn)該聚合對象的迭代。
????? 通過迭代器模式,使得聚合對象的結(jié)構(gòu)更加簡單,它不需要關(guān)注它元素的遍歷,只需要專注它應(yīng)該專注的事情,這樣就更加符合單一職責(zé)原則了。
?????? 參與者:
????????? Iterator:?抽象迭代器:所有迭代器都需要實(shí)現(xiàn)的接口,提供了游走聚合對象元素之間的方法。
????????? ConcreteIterator:?具體迭代器。利用這個具體的迭代器能夠?qū)唧w的聚合對象進(jìn)行遍歷。每一個聚合對象都應(yīng)該對應(yīng)一個具體的迭代器。
????????? Aggregate:?抽象聚合類。
????????? ConcreteAggregate:?具體聚合類。實(shí)現(xiàn)creatorIterator()方法,返回該聚合對象的迭代器。
5、中介者模式(Mediator)
????? 租房各位都有過的經(jīng)歷吧!在這個過程中中介結(jié)構(gòu)扮演著很重要的角色,它在這里起到一個中間者的作用,給我們和房主互相傳遞信息。在外面軟件的世界里同樣需要這樣一個中間者。在我們的系統(tǒng)中有時候會存在著對象與對象之間存在著很強(qiáng)、復(fù)雜的關(guān)聯(lián)關(guān)系,如果讓他們之間有直接的聯(lián)系的話,必定會導(dǎo)致整個系統(tǒng)變得非常復(fù)雜,而且可擴(kuò)展性很差!在前面我們就知道如果兩個類之間沒有不必彼此通信,我們就不應(yīng)該讓他們有直接的關(guān)聯(lián)關(guān)系,如果實(shí)在是需要通信的話,我們可以通過第三者來轉(zhuǎn)發(fā)他們的請求。同樣,這里我們利用中介者來解決這個問題。
????? 所謂中介者模式就是用一個中介對象來封裝一系列的對象交互,中介者使各對象不需要顯式地相互引用,從而使其耦合松散,而且可以獨(dú)立地改變它們之間的交互。在中介者模式中,中介對象用來封裝對象之間的關(guān)系,各個對象可以不需要知道具體的信息通過中介者對象就可以實(shí)現(xiàn)相互通信。它減少了對象之間的互相關(guān)系,提供了系統(tǒng)可復(fù)用性,簡化了系統(tǒng)的結(jié)構(gòu)。
????? 在中介者模式中,各個對象不需要互相知道了解,他們只需要知道中介者對象即可,但是中介者對象就必須要知道所有的對象和他們之間的關(guān)聯(lián)關(guān)系,正是因?yàn)檫@樣就導(dǎo)致了中介者對象的結(jié)構(gòu)過于復(fù)雜,承擔(dān)了過多的職責(zé),同時它也是整個系統(tǒng)的核心所在,它有問題將會導(dǎo)致整個系統(tǒng)的問題。所以如果在系統(tǒng)的設(shè)計過程中如果出現(xiàn)“多對多”的復(fù)雜關(guān)系群時,千萬別急著使用中介者模式,而是要仔細(xì)思考是不是您設(shè)計的系統(tǒng)存在問題。
????? 參與者:
???????? Mediator:?抽象中介者。定義了同事對象到中介者對象之間的接口。
???????? ConcreteMediator:?具體中介者。實(shí)現(xiàn)抽象中介者的方法,它需要知道所有的具體同事類,同時需要從具體的同事類那里接收信息,并且向具體的同事類發(fā)送信息。
???????? Colleague:?抽象同事類。
???????? ConcreteColleague:?具體同事類。每個具體同事類都只需要知道自己的行為即可,但是他們都需要認(rèn)識中介者。
6、備忘錄模式(Memento)
?????后悔藥人人都想要,但是事實(shí)卻是殘酷的,根本就沒有后悔藥可買,但是也不僅如此,在軟件的世界里就有后悔藥!備忘錄模式就是一種后悔藥,它給我們的軟件提供后悔藥的機(jī)制,通過它可以使系統(tǒng)恢復(fù)到某一特定的歷史狀態(tài)。
????? 所謂備忘錄模式就是在不破壞封裝的前提下,捕獲一個對象的內(nèi)部狀態(tài),并在該對象之外保存這個狀態(tài),這樣可以在以后將對象恢復(fù)到原先保存的狀態(tài)。它實(shí)現(xiàn)了對信息的封裝,使得客戶不需要關(guān)心狀態(tài)保存的細(xì)節(jié)。保存就要消耗資源,所以備忘錄模式的缺點(diǎn)就在于消耗資源。如果類的成員變量過多,勢必會占用比較大的資源,而且每一次保存都會消耗一定的內(nèi)存。
????? 參與者:
?????????Originator:?原發(fā)器。負(fù)責(zé)創(chuàng)建一個備忘錄,用以記錄當(dāng)前對象的內(nèi)部狀態(tài),通過也可以使用它來利用備忘錄恢復(fù)內(nèi)部狀態(tài)。同時原發(fā)器還可以根據(jù)需要決定Memento存儲Originator的那些內(nèi)部狀態(tài)。
?????????Memento:?備忘錄。用于存儲Originator的內(nèi)部狀態(tài),并且可以防止Originator以外的對象訪問Memento。在備忘錄Memento中有兩個接口,其中Caretaker只能看到備忘錄中的窄接口,它只能將備忘錄傳遞給其他對象。Originator可以看到寬接口,允許它訪問返回到先前狀態(tài)的所有數(shù)據(jù)。
?????????Caretaker:?負(fù)責(zé)人。負(fù)責(zé)保存好備忘錄,不能對備忘錄的內(nèi)容進(jìn)行操作和訪問,只能夠?qū)渫泜鬟f給其他對象。
7、觀察者模式(Observer)
????? 何謂觀察者模式?觀察者模式定義了對象之間的一對多依賴關(guān)系,這樣一來,當(dāng)一個對象改變狀態(tài)時,它的所有依賴者都會收到通知并且自動更新。
????? 在這里,發(fā)生改變的對象稱之為觀察目標(biāo),而被通知的對象稱之為觀察者。一個觀察目標(biāo)可以對應(yīng)多個觀察者,而且這些觀察者之間沒有相互聯(lián)系,所以么可以根據(jù)需要增加和刪除觀察者,使得系統(tǒng)更易于擴(kuò)展。
????? 所以觀察者提供了一種對象設(shè)計,讓主題和觀察者之間以松耦合的方式結(jié)合。
????? 參與者:
??????????Subject:目標(biāo)。他把所有對觀察者對戲的引用保存在一個聚集里,每一個主題都可以有多個觀察者。
??????????Observer:觀察者。為所有的具體觀察者定義一個接口,在得到主題的通知時能夠及時的更新自己。
??????????ConcreteSubject:具體主題。將有關(guān)狀態(tài)存入具體觀察者對象。在具體主題發(fā)生改變時,給所有的觀察者發(fā)出通知。
??????????ConcreteObserver:具體觀察者。實(shí)現(xiàn)抽象觀察者角色所要求的更新接口,以便使本身的狀態(tài)與主題狀態(tài)相協(xié)調(diào)。
8、狀態(tài)模式(State)
????? 在很多情況下我們對象的行為依賴于它的一個或者多個變化的屬性,這些可變的屬性我們稱之為狀態(tài),也就是說行為依賴狀態(tài),即當(dāng)該對象因?yàn)樵谕獠康幕佣鴮?dǎo)致他的狀態(tài)發(fā)生變化,從而它的行為也會做出相應(yīng)的變化。對于這種情況,我們是不能用行為來控制狀態(tài)的變化,而應(yīng)該站在狀態(tài)的角度來思考行為,即是什么狀態(tài)就要做出什么樣的行為。這個就是狀態(tài)模式。
??????所以狀態(tài)模式就是允許對象在內(nèi)部狀態(tài)發(fā)生改變時改變它的行為,對象看起來好像修改了它的類。
????? 在狀態(tài)模式中我們可以減少大塊的if…else語句,它是允許態(tài)轉(zhuǎn)換邏輯與狀態(tài)對象合成一體,但是減少if…else語句的代價就是會換來大量的類,所以狀態(tài)模式勢必會增加系統(tǒng)中類或者對象的個數(shù)。
????? 同時狀態(tài)模式是將所有與某個狀態(tài)有關(guān)的行為放到一個類中,并且可以方便地增加新的狀態(tài),只需要改變對象狀態(tài)即可改變對象的行為。但是這樣就會導(dǎo)致系統(tǒng)的結(jié)構(gòu)和實(shí)現(xiàn)都會比較復(fù)雜,如果使用不當(dāng)就會導(dǎo)致程序的結(jié)構(gòu)和代碼混亂,不利于維護(hù)。
????? 參與者:
?????????Context:環(huán)境類。可以包括一些內(nèi)部狀態(tài)。?
?????????State:?抽象狀態(tài)類。State定義了一個所有具體狀態(tài)的共同接口,任何狀態(tài)都實(shí)現(xiàn)這個相同的接口,這樣一來,狀態(tài)之間就可以互相轉(zhuǎn)換了。?
?????????ConcreteState:具體狀態(tài)類。具體狀態(tài)類,用于處理來自Context的請求,每一個ConcreteState都提供了它對自己請求的實(shí)現(xiàn),所以,當(dāng)Context改變狀態(tài)時行為也會跟著改變。
9、策略模式(Strategy)
????? 我們知道一件事可能會有很多種方式來實(shí)現(xiàn)它,但是其中總有一種最高效的方式,在軟件開發(fā)的世界里面同樣如此,我們也有很多中方法來實(shí)現(xiàn)一個功能,但是我們需要一種簡單、高效的方式來實(shí)現(xiàn)它,使得系統(tǒng)能夠非常靈活,這就是策略模式。
????? 所以策略模式就是定義了算法族,分別封裝起來,讓他們之前可以互相轉(zhuǎn)換,此模式然該算法的變化獨(dú)立于使用算法的客戶。
????? 在策略模式中它將這些解決問題的方法定義成一個算法群,每一個方法都對應(yīng)著一個具體的算法,這里的一個算法我就稱之為一個策略。雖然策略模式定義了算法,但是它并不提供算法的選擇,即什么算法對于什么問題最合適這是策略模式所不關(guān)心的,所以對于策略的選擇還是要客戶端來做。客戶必須要清楚的知道每個算法之間的區(qū)別和在什么時候什么地方使用什么策略是最合適的,這樣就增加客戶端的負(fù)擔(dān)。
????? 同時策略模式也非常完美的符合了“開閉原則”,用戶可以在不修改原有系統(tǒng)的基礎(chǔ)上選擇算法或行為,也可以靈活地增加新的算法或行為。但是一個策略對應(yīng)一個類將會是系統(tǒng)產(chǎn)生很多的策略類。
????? 參與者:
?????????Context:?環(huán)境類。維護(hù)一個Strategy對象的引用,用一個ConcreteStrategy來配置,可定義一個接口來讓Strategy訪問它的數(shù)據(jù)。?
?????????Strategy:?抽象策略類。定義所有支持算法的公共接口。Context使用這個接口來調(diào)用某個Concretestrategy定義的算法。?
?????????ConcreteStrategy:?具體策略類。封裝了具體的算法實(shí)現(xiàn)。
10、模板方法模式(Template Method)
????? 有些時候我們做某幾件事情的步驟都差不多,僅有那么一小點(diǎn)的不同,在軟件開發(fā)的世界里同樣如此,如果我們都將這些步驟都一一做的話,費(fèi)時費(fèi)力不討好。所以我們可以將這些步驟分解、封裝起來,然后利用繼承的方式來繼承即可,當(dāng)然不同的可以自己重寫實(shí)現(xiàn)嘛!這就是模板方法模式提供的解決方案。
????? 所謂模板方法模式就是在一個方法中定義一個算法的骨架,而將一些步驟延遲到子類中。模板方法使得子類可以在不改變算法結(jié)構(gòu)的情況下,重新定義算法中的某些步驟。
????? 模板方法模式就是基于繼承的代碼復(fù)用技術(shù)的。在模板方法模式中,我們可以將相同部分的代碼放在父類中,而將不同的代碼放入不同的子類中。也就是說我們需要聲明一個抽象的父類,將部分邏輯以具體方法以及具體構(gòu)造函數(shù)的形式實(shí)現(xiàn),然后聲明一些抽象方法讓子類來實(shí)現(xiàn)剩余的邏輯,不同的子類可以以不同的方式來實(shí)現(xiàn)這些邏輯。所以模板方法的模板其實(shí)就是一個普通的方法,只不過這個方法是將算法實(shí)現(xiàn)的步驟封裝起來的。
?
????? 參與者:
?????????AbstractClass:?抽象類。實(shí)現(xiàn)了一個模板,實(shí)現(xiàn)算法的基本骨架,具體子類將重定義primitiveOperation()方法以實(shí)現(xiàn)一個算法步驟。
?????????ConcreteClass:? 具體子類。實(shí)現(xiàn)primitiveOperation()方法以完成算法中與特定子類相關(guān)的步驟。
11、訪問者模式(Visitor)
????? 訪問者模式俗稱23大設(shè)計模式中最難的一個。除了結(jié)構(gòu)復(fù)雜外,理解也比較難。在我們軟件開發(fā)中我們可能會對同一個對象有不同的處理,如果我們都做分別的處理,將會產(chǎn)生災(zāi)難性的錯誤。對于這種問題,訪問者模式提供了比較好的解決方案。
?????訪問者模式即表示一個作用于某對象結(jié)構(gòu)中的各元素的操作,它使我們可以在不改變各元素的類的前提下定義作用于這些元素的新操作。
????? 訪問者模式的目的是封裝一些施加于某種數(shù)據(jù)結(jié)構(gòu)元素之上的操作,一旦這些操作需要修改的話,接受這個操作的數(shù)據(jù)結(jié)構(gòu)可以保持不變。為不同類型的元素提供多種訪問操作方式,且可以在不修改原有系統(tǒng)的情況下增加新的操作方式。同時我們還需要明確一點(diǎn)那就是訪問者模式是適用于那些數(shù)據(jù)結(jié)構(gòu)比較穩(wěn)定的,因?yàn)樗菍?shù)據(jù)的操作與數(shù)據(jù)結(jié)構(gòu)進(jìn)行分離了,如果某個系統(tǒng)的數(shù)據(jù)結(jié)構(gòu)相對穩(wěn)定,但是操作算法易于變化的話,就比較適用適用訪問者模式,因?yàn)樵L問者模式使得算法操作的增加變得比較簡單了。
????? 參與者:
?????????Vistor:?抽象訪問者。為該對象結(jié)構(gòu)中的ConcreteElement的每一個類聲明的一個操作。?
?????????ConcreteVisitor:?具體訪問者。實(shí)現(xiàn)Visitor申明的每一個操作,每一個操作實(shí)現(xiàn)算法的一部分。?
?????????Element:?抽象元素。定義一個Accept操作,它以一個訪問者為參數(shù)。?
?????????ConcreteElement:?具體元素 。實(shí)現(xiàn)Accept操作。?
?????????ObjectStructure:?對象結(jié)構(gòu)。能夠枚舉它的元素,可以提供一個高層的接口來允許訪問者訪問它的元素。
五、更多
????? 上面只是對各個設(shè)計模式的一個簡單的總結(jié),下面我將列出詳情,各位看客有興趣的可以點(diǎn)點(diǎn):
???????? 01、設(shè)計模式讀書筆記-----簡單工廠模式
???????? 02、設(shè)計模式讀書筆記-----工廠方法模式
???????? 03、設(shè)計模式讀書筆記-----抽象工廠模式
???????? 04、設(shè)計模式讀書筆記-----建造者模式
???????? 05、設(shè)計模式讀書筆記-----原型模式
???????? 06、設(shè)計模式讀書筆記-----單例模式
???????? 07、設(shè)計模式讀書筆記-----適配器模式
???????? 08、設(shè)計模式讀書筆記-----橋接模式
???????? 09、設(shè)計模式讀書筆記-----組合模式
???????? 10、設(shè)計模式讀書筆記-----裝飾者模式
???????? 11、設(shè)計模式讀書筆記-----外觀模式
???????? 12、設(shè)計模式讀書筆記----享元模式
???????? 13、設(shè)計模式讀書筆記-----代理模式
???????? 14、設(shè)計模式讀書筆記-----職責(zé)鏈模式
???????? 15、設(shè)計模式讀書筆記-----命令模式
???????? 16、設(shè)計模式讀書筆記-----解釋器模式
???????? 17、設(shè)計模式讀書筆記-----迭代器模式
???????? 18、設(shè)計模式讀書筆記-----中介者模式
???????? 19、設(shè)計模式讀書筆記-----備忘錄模式
???????? 20、設(shè)計模式讀書筆記-----觀察者模式
???????? 21、設(shè)計模式讀書筆記-----狀態(tài)模式
???????? 22、設(shè)計模式讀書筆記-----策略模式
???????? 23、設(shè)計模式讀書筆記-----模板方法模式
???????? 24、設(shè)計模式讀書筆記-----訪問者模式
六、最后
????? 感謝Eric Freeman , Elisabeth Freeman , Kathy Sierra & Bert Bates所編寫的《Head First design patterns》,正是這本書將我領(lǐng)入設(shè)計模式的大門,雖然只是剛剛跨過門檻,但早已陶醉于那濃濃的、醇正的知識香中。還要感謝劉偉老師的PPT,您的教程給了我一個很好的參考。
????? 雖然看完了設(shè)計模式,但這并不是結(jié)束,而是剛剛開始,在以后的項(xiàng)目過程中,我會盡量去優(yōu)化,思考。
????? 誠然,最近在做項(xiàng)目的過程中深感基礎(chǔ)不夠扎實(shí),所以下一步就是java基礎(chǔ)了:think in java ,I must conquer you!!!!
????? 博文有點(diǎn)兒長,感謝各位看客能夠看完,如果覺得不錯,請推薦個吧!!!!
轉(zhuǎn)載于:https://www.cnblogs.com/freebird92/p/9325723.html
總結(jié)
- 上一篇: mysql从库故障恢复步骤(删除数据重新
- 下一篇: 设计模式初探之模板方法(Template