java中的23種設(shè)計(jì)模式--最最最詳細(xì)總結(jié)和使用時(shí)注意事項(xiàng)

設(shè)計(jì)模式簡(jiǎn)介

設(shè)計(jì)模式(Design pattern)代表了最佳的實(shí)踐塘淑,通常被有經(jīng)驗(yàn)的面向?qū)ο蟮能浖_(kāi)發(fā)人員所采用。設(shè)計(jì)模式是軟件開(kāi)發(fā)人員在軟件開(kāi)發(fā)過(guò)程中面臨的一般問(wèn)題的解決方案盒犹。這些解決方案是眾多軟件開(kāi)發(fā)人員經(jīng)過(guò)相當(dāng)長(zhǎng)的一段時(shí)間的試驗(yàn)和錯(cuò)誤總結(jié)出來(lái)的坐梯。
設(shè)計(jì)模式是一套被反復(fù)使用的、多數(shù)人知曉的毅人、經(jīng)過(guò)分類(lèi)編目的托启、代碼設(shè)計(jì)經(jīng)驗(yàn)的總結(jié)宅倒。使用設(shè)計(jì)模式是為了重用代碼、讓代碼更容易被他人理解驾中、保證代碼可靠性唉堪。 毫無(wú)疑問(wèn),設(shè)計(jì)模式于己于他人于系統(tǒng)都是多贏的肩民,設(shè)計(jì)模式使代碼編制真正工程化唠亚,設(shè)計(jì)模式是軟件工程的基石,如同大廈的一塊塊磚石一樣持痰。項(xiàng)目中合理地運(yùn)用設(shè)計(jì)模式可以完美地解決很多問(wèn)題灶搜,每種模式在現(xiàn)實(shí)中都有相應(yīng)的原理來(lái)與之對(duì)應(yīng),每種模式都描述了一個(gè)在我們周?chē)粩嘀貜?fù)發(fā)生的問(wèn)題工窍,以及該問(wèn)題的核心解決方案割卖,這也是設(shè)計(jì)模式能被廣泛應(yīng)用的原因。

工廠模式

工廠模式(Factory Pattern)是 Java 中最常用的設(shè)計(jì)模式之一患雏。這種類(lèi)型的設(shè)計(jì)模式屬于創(chuàng)建型模式鹏溯,它提供了一種創(chuàng)建對(duì)象的最佳方式。

在工廠模式中淹仑,我們?cè)趧?chuàng)建對(duì)象時(shí)不會(huì)對(duì)客戶端暴露創(chuàng)建邏輯丙挽,并且是通過(guò)使用一個(gè)共同的接口來(lái)指向新創(chuàng)建的對(duì)象。

介紹
意圖:定義一個(gè)創(chuàng)建對(duì)象的接口匀借,讓其子類(lèi)自己決定實(shí)例化哪一個(gè)工廠類(lèi)颜阐,工廠模式使其創(chuàng)建過(guò)程延遲到子類(lèi)進(jìn)行。

主要解決:主要解決接口選擇的問(wèn)題吓肋。

何時(shí)使用:我們明確地計(jì)劃不同條件下創(chuàng)建不同實(shí)例時(shí)凳怨。

如何解決:讓其子類(lèi)實(shí)現(xiàn)工廠接口,返回的也是一個(gè)抽象的產(chǎn)品。

關(guān)鍵代碼:創(chuàng)建過(guò)程在其子類(lèi)執(zhí)行肤舞。


QQ截圖20200520153713.png

抽象工廠模式

抽象工廠模式(Abstract Factory Pattern)是圍繞一個(gè)超級(jí)工廠創(chuàng)建其他工廠紫新。該超級(jí)工廠又稱為其他工廠的工廠。這種類(lèi)型的設(shè)計(jì)模式屬于創(chuàng)建型模式李剖,它提供了一種創(chuàng)建對(duì)象的最佳方式弊琴。

在抽象工廠模式中,接口是負(fù)責(zé)創(chuàng)建一個(gè)相關(guān)對(duì)象的工廠杖爽,不需要顯式指定它們的類(lèi)。每個(gè)生成的工廠都能按照工廠模式提供對(duì)象紫皇。

介紹
意圖:提供一個(gè)創(chuàng)建一系列相關(guān)或相互依賴對(duì)象的接口慰安,而無(wú)需指定它們具體的類(lèi)。

主要解決:主要解決接口選擇的問(wèn)題聪铺。

何時(shí)使用:系統(tǒng)的產(chǎn)品有多于一個(gè)的產(chǎn)品族化焕,而系統(tǒng)只消費(fèi)其中某一族的產(chǎn)品。

如何解決:在一個(gè)產(chǎn)品族里面铃剔,定義多個(gè)產(chǎn)品撒桨。

關(guān)鍵代碼:在一個(gè)工廠里聚合多個(gè)同類(lèi)產(chǎn)品。

應(yīng)用實(shí)例:工作了键兜,為了參加一些聚會(huì)凤类,肯定有兩套或多套衣服吧,比如說(shuō)有商務(wù)裝(成套普气,一系列具體產(chǎn)品)谜疤、時(shí)尚裝(成套,一系列具體產(chǎn)品)现诀,甚至對(duì)于一個(gè)家庭來(lái)說(shuō)夷磕,可能有商務(wù)女裝、商務(wù)男裝仔沿、時(shí)尚女裝坐桩、時(shí)尚男裝,這些也都是成套的封锉,即一系列具體產(chǎn)品绵跷。假設(shè)一種情況(現(xiàn)實(shí)中是不存在的,要不然烘浦,沒(méi)法進(jìn)入共產(chǎn)主義了抖坪,但有利于說(shuō)明抽象工廠模式),在您的家中闷叉,某一個(gè)衣柜(具體工廠)只能存放某一種這樣的衣服(成套擦俐,一系列具體產(chǎn)品),每次拿這種成套的衣服時(shí)也自然要從這個(gè)衣柜中取出了握侧。用 OOP 的思想去理解蚯瞧,所有的衣柜(具體工廠)都是衣柜類(lèi)的(抽象工廠)某一個(gè)嘿期,而每一件成套的衣服又包括具體的上衣(某一具體產(chǎn)品),褲子(某一具體產(chǎn)品)埋合,這些具體的上衣其實(shí)也都是上衣(抽象產(chǎn)品)备徐,具體的褲子也都是褲子(另一個(gè)抽象產(chǎn)品)。

優(yōu)點(diǎn):當(dāng)一個(gè)產(chǎn)品族中的多個(gè)對(duì)象被設(shè)計(jì)成一起工作時(shí)甚颂,它能保證客戶端始終只使用同一個(gè)產(chǎn)品族中的對(duì)象蜜猾。

缺點(diǎn):產(chǎn)品族擴(kuò)展非常困難,要增加一個(gè)系列的某一產(chǎn)品振诬,既要在抽象的 Creator 里加代碼蹭睡,又要在具體的里面加代碼。

使用場(chǎng)景: 1赶么、QQ 換皮膚抹蚀,一整套一起換葬燎。 2比勉、生成不同操作系統(tǒng)的程序蚯根。

注意事項(xiàng):產(chǎn)品族難擴(kuò)展,產(chǎn)品等級(jí)易擴(kuò)展


QQ截圖20200520153742.png

單例模式

單例模式(Singleton Pattern)是 Java 中最簡(jiǎn)單的設(shè)計(jì)模式之一放闺。這種類(lèi)型的設(shè)計(jì)模式屬于創(chuàng)建型模式祟昭,它提供了一種創(chuàng)建對(duì)象的最佳方式。

這種模式涉及到一個(gè)單一的類(lèi)怖侦,該類(lèi)負(fù)責(zé)創(chuàng)建自己的對(duì)象从橘,同時(shí)確保只有單個(gè)對(duì)象被創(chuàng)建。這個(gè)類(lèi)提供了一種訪問(wèn)其唯一的對(duì)象的方式础钠,可以直接訪問(wèn)恰力,不需要實(shí)例化該類(lèi)的對(duì)象。

注意:

1旗吁、單例類(lèi)只能有一個(gè)實(shí)例踩萎。
2、單例類(lèi)必須自己創(chuàng)建自己的唯一實(shí)例很钓。
3香府、單例類(lèi)必須給所有其他對(duì)象提供這一實(shí)例。
介紹
意圖:保證一個(gè)類(lèi)僅有一個(gè)實(shí)例码倦,并提供一個(gè)訪問(wèn)它的全局訪問(wèn)點(diǎn)企孩。

主要解決:一個(gè)全局使用的類(lèi)頻繁地創(chuàng)建與銷(xiāo)毀。

何時(shí)使用:當(dāng)您想控制實(shí)例數(shù)目袁稽,節(jié)省系統(tǒng)資源的時(shí)候勿璃。

如何解決:判斷系統(tǒng)是否已經(jīng)有這個(gè)單例,如果有則返回,如果沒(méi)有則創(chuàng)建补疑。

關(guān)鍵代碼:構(gòu)造函數(shù)是私有的歧沪。

應(yīng)用實(shí)例:

1、一個(gè)班級(jí)只有一個(gè)班主任莲组。
2诊胞、Windows 是多進(jìn)程多線程的,在操作一個(gè)文件的時(shí)候锹杈,就不可避免地出現(xiàn)多個(gè)進(jìn)程或線程同時(shí)操作一個(gè)文件的現(xiàn)象撵孤,所以所有文件的處理必須通過(guò)唯一的實(shí)例來(lái)進(jìn)行。
3竭望、一些設(shè)備管理器常常設(shè)計(jì)為單例模式早直,比如一個(gè)電腦有兩臺(tái)打印機(jī),在輸出的時(shí)候就要處理不能兩臺(tái)打印機(jī)打印同一個(gè)文件市框。
優(yōu)點(diǎn):

1、在內(nèi)存里只有一個(gè)實(shí)例糕韧,減少了內(nèi)存的開(kāi)銷(xiāo)枫振,尤其是頻繁的創(chuàng)建和銷(xiāo)毀實(shí)例(比如管理學(xué)院首頁(yè)頁(yè)面緩存)。
2萤彩、避免對(duì)資源的多重占用(比如寫(xiě)文件操作)粪滤。
缺點(diǎn):沒(méi)有接口,不能繼承雀扶,與單一職責(zé)原則沖突杖小,一個(gè)類(lèi)應(yīng)該只關(guān)心內(nèi)部邏輯,而不關(guān)心外面怎么樣來(lái)實(shí)例化愚墓。

使用場(chǎng)景:

1予权、要求生產(chǎn)唯一序列號(hào)。
2浪册、WEB 中的計(jì)數(shù)器扫腺,不用每次刷新都在數(shù)據(jù)庫(kù)里加一次,用單例先緩存起來(lái)村象。
3笆环、創(chuàng)建的一個(gè)對(duì)象需要消耗的資源過(guò)多,比如 I/O 與數(shù)據(jù)庫(kù)的連接等厚者。
注意事項(xiàng):getInstance() 方法中需要使用同步鎖 synchronized (Singleton.class) 防止多線程同時(shí)進(jìn)入造成 instance 被多次實(shí)例化躁劣。


QQ截圖20200520153821.png

建造者模式

建造者模式(Builder Pattern)使用多個(gè)簡(jiǎn)單的對(duì)象一步一步構(gòu)建成一個(gè)復(fù)雜的對(duì)象。這種類(lèi)型的設(shè)計(jì)模式屬于創(chuàng)建型模式库菲,它提供了一種創(chuàng)建對(duì)象的最佳方式账忘。

一個(gè) Builder 類(lèi)會(huì)一步一步構(gòu)造最終的對(duì)象。該 Builder 類(lèi)是獨(dú)立于其他對(duì)象的。

介紹
意圖:將一個(gè)復(fù)雜的構(gòu)建與其表示相分離闪萄,使得同樣的構(gòu)建過(guò)程可以創(chuàng)建不同的表示梧却。

主要解決:主要解決在軟件系統(tǒng)中,有時(shí)候面臨著"一個(gè)復(fù)雜對(duì)象"的創(chuàng)建工作败去,其通常由各個(gè)部分的子對(duì)象用一定的算法構(gòu)成放航;由于需求的變化,這個(gè)復(fù)雜對(duì)象的各個(gè)部分經(jīng)常面臨著劇烈的變化圆裕,但是將它們組合在一起的算法卻相對(duì)穩(wěn)定广鳍。

何時(shí)使用:一些基本部件不會(huì)變,而其組合經(jīng)常變化的時(shí)候吓妆。

如何解決:將變與不變分離開(kāi)赊时。

關(guān)鍵代碼:建造者:創(chuàng)建和提供實(shí)例,導(dǎo)演:管理建造出來(lái)的實(shí)例的依賴關(guān)系行拢。

應(yīng)用實(shí)例: 1祖秒、去肯德基,漢堡舟奠、可樂(lè)竭缝、薯?xiàng)l、炸雞翅等是不變的沼瘫,而其組合是經(jīng)常變化的抬纸,生成出所謂的"套餐"。 2耿戚、JAVA 中的 StringBuilder湿故。

優(yōu)點(diǎn): 1、建造者獨(dú)立膜蛔,易擴(kuò)展坛猪。 2、便于控制細(xì)節(jié)風(fēng)險(xiǎn)皂股。

缺點(diǎn): 1砚哆、產(chǎn)品必須有共同點(diǎn),范圍有限制屑墨。 2躁锁、如內(nèi)部變化復(fù)雜,會(huì)有很多的建造類(lèi)卵史。

使用場(chǎng)景: 1战转、需要生成的對(duì)象具有復(fù)雜的內(nèi)部結(jié)構(gòu)。 2以躯、需要生成的對(duì)象內(nèi)部屬性本身相互依賴槐秧。

注意事項(xiàng):與工廠模式的區(qū)別是:建造者模式更加關(guān)注與零件裝配的順序啄踊。


QQ截圖20200520153844.png

原型模式

原型模式(Prototype Pattern)是用于創(chuàng)建重復(fù)的對(duì)象,同時(shí)又能保證性能刁标。這種類(lèi)型的設(shè)計(jì)模式屬于創(chuàng)建型模式颠通,它提供了一種創(chuàng)建對(duì)象的最佳方式。

這種模式是實(shí)現(xiàn)了一個(gè)原型接口膀懈,該接口用于創(chuàng)建當(dāng)前對(duì)象的克隆顿锰。當(dāng)直接創(chuàng)建對(duì)象的代價(jià)比較大時(shí),則采用這種模式启搂。例如硼控,一個(gè)對(duì)象需要在一個(gè)高代價(jià)的數(shù)據(jù)庫(kù)操作之后被創(chuàng)建。我們可以緩存該對(duì)象胳赌,在下一個(gè)請(qǐng)求時(shí)返回它的克隆牢撼,在需要的時(shí)候更新數(shù)據(jù)庫(kù),以此來(lái)減少數(shù)據(jù)庫(kù)調(diào)用疑苫。

介紹
意圖:用原型實(shí)例指定創(chuàng)建對(duì)象的種類(lèi)熏版,并且通過(guò)拷貝這些原型創(chuàng)建新的對(duì)象。

主要解決:在運(yùn)行期建立和刪除原型捍掺。

何時(shí)使用: 1撼短、當(dāng)一個(gè)系統(tǒng)應(yīng)該獨(dú)立于它的產(chǎn)品創(chuàng)建,構(gòu)成和表示時(shí)乡小。 2、當(dāng)要實(shí)例化的類(lèi)是在運(yùn)行時(shí)刻指定時(shí)饵史,例如满钟,通過(guò)動(dòng)態(tài)裝載。 3胳喷、為了避免創(chuàng)建一個(gè)與產(chǎn)品類(lèi)層次平行的工廠類(lèi)層次時(shí)湃番。 4、當(dāng)一個(gè)類(lèi)的實(shí)例只能有幾個(gè)不同狀態(tài)組合中的一種時(shí)吭露。建立相應(yīng)數(shù)目的原型并克隆它們可能比每次用合適的狀態(tài)手工實(shí)例化該類(lèi)更方便一些吠撮。

如何解決:利用已有的一個(gè)原型對(duì)象,快速地生成和原型對(duì)象一樣的實(shí)例讲竿。

關(guān)鍵代碼: 1泥兰、實(shí)現(xiàn)克隆操作,在 JAVA 繼承 Cloneable题禀,重寫(xiě) clone()鞋诗,在 .NET 中可以使用 Object 類(lèi)的 MemberwiseClone() 方法來(lái)實(shí)現(xiàn)對(duì)象的淺拷貝或通過(guò)序列化的方式來(lái)實(shí)現(xiàn)深拷貝。 2迈嘹、原型模式同樣用于隔離類(lèi)對(duì)象的使用者和具體類(lèi)型(易變類(lèi))之間的耦合關(guān)系削彬,它同樣要求這些"易變類(lèi)"擁有穩(wěn)定的接口全庸。

應(yīng)用實(shí)例: 1、細(xì)胞分裂融痛。 2壶笼、JAVA 中的 Object clone() 方法。

優(yōu)點(diǎn): 1雁刷、性能提高覆劈。 2、逃避構(gòu)造函數(shù)的約束安券。

缺點(diǎn): 1墩崩、配備克隆方法需要對(duì)類(lèi)的功能進(jìn)行通盤(pán)考慮,這對(duì)于全新的類(lèi)不是很難侯勉,但對(duì)于已有的類(lèi)不一定很容易鹦筹,特別當(dāng)一個(gè)類(lèi)引用不支持串行化的間接對(duì)象,或者引用含有循環(huán)結(jié)構(gòu)的時(shí)候址貌。 2铐拐、必須實(shí)現(xiàn) Cloneable 接口。

使用場(chǎng)景: 1练对、資源優(yōu)化場(chǎng)景遍蟋。 2、類(lèi)初始化需要消化非常多的資源螟凭,這個(gè)資源包括數(shù)據(jù)虚青、硬件資源等。 3螺男、性能和安全要求的場(chǎng)景棒厘。 4、通過(guò) new 產(chǎn)生一個(gè)對(duì)象需要非常繁瑣的數(shù)據(jù)準(zhǔn)備或訪問(wèn)權(quán)限下隧,則可以使用原型模式奢人。 5、一個(gè)對(duì)象多個(gè)修改者的場(chǎng)景淆院。 6何乎、一個(gè)對(duì)象需要提供給其他對(duì)象訪問(wèn),而且各個(gè)調(diào)用者可能都需要修改其值時(shí)土辩,可以考慮使用原型模式拷貝多個(gè)對(duì)象供調(diào)用者使用支救。 7、在實(shí)際項(xiàng)目中拷淘,原型模式很少單獨(dú)出現(xiàn)搂妻,一般是和工廠方法模式一起出現(xiàn),通過(guò) clone 的方法創(chuàng)建一個(gè)對(duì)象辕棚,然后由工廠方法提供給調(diào)用者欲主。原型模式已經(jīng)與 Java 融為渾然一體邓厕,大家可以隨手拿來(lái)使用。

注意事項(xiàng):與通過(guò)對(duì)一個(gè)類(lèi)進(jìn)行實(shí)例化來(lái)構(gòu)造新對(duì)象不同的是扁瓢,原型模式是通過(guò)拷貝一個(gè)現(xiàn)有對(duì)象生成新對(duì)象的详恼。淺拷貝實(shí)現(xiàn) Cloneable,重寫(xiě)引几,深拷貝是通過(guò)實(shí)現(xiàn) Serializable 讀取二進(jìn)制流昧互。


QQ截圖20200520153904.png

適配器模式

適配器模式(Adapter Pattern)是作為兩個(gè)不兼容的接口之間的橋梁。這種類(lèi)型的設(shè)計(jì)模式屬于結(jié)構(gòu)型模式伟桅,它結(jié)合了兩個(gè)獨(dú)立接口的功能敞掘。

這種模式涉及到一個(gè)單一的類(lèi),該類(lèi)負(fù)責(zé)加入獨(dú)立的或不兼容的接口功能楣铁。舉個(gè)真實(shí)的例子玖雁,讀卡器是作為內(nèi)存卡和筆記本之間的適配器。您將內(nèi)存卡插入讀卡器盖腕,再將讀卡器插入筆記本赫冬,這樣就可以通過(guò)筆記本來(lái)讀取內(nèi)存卡。

我們通過(guò)下面的實(shí)例來(lái)演示適配器模式的使用溃列。其中劲厌,音頻播放器設(shè)備只能播放 mp3 文件,通過(guò)使用一個(gè)更高級(jí)的音頻播放器來(lái)播放 vlc 和 mp4 文件听隐。

介紹
意圖:將一個(gè)類(lèi)的接口轉(zhuǎn)換成客戶希望的另外一個(gè)接口补鼻。適配器模式使得原本由于接口不兼容而不能一起工作的那些類(lèi)可以一起工作。

主要解決:主要解決在軟件系統(tǒng)中雅任,常常要將一些"現(xiàn)存的對(duì)象"放到新的環(huán)境中风范,而新環(huán)境要求的接口是現(xiàn)對(duì)象不能滿足的。

何時(shí)使用: 1椿访、系統(tǒng)需要使用現(xiàn)有的類(lèi)乌企,而此類(lèi)的接口不符合系統(tǒng)的需要虑润。 2成玫、想要建立一個(gè)可以重復(fù)使用的類(lèi),用于與一些彼此之間沒(méi)有太大關(guān)聯(lián)的一些類(lèi)拳喻,包括一些可能在將來(lái)引進(jìn)的類(lèi)一起工作哭当,這些源類(lèi)不一定有一致的接口。 3冗澈、通過(guò)接口轉(zhuǎn)換钦勘,將一個(gè)類(lèi)插入另一個(gè)類(lèi)系中。(比如老虎和飛禽亚亲,現(xiàn)在多了一個(gè)飛虎彻采,在不增加實(shí)體的需求下腐缤,增加一個(gè)適配器,在里面包容一個(gè)虎對(duì)象肛响,實(shí)現(xiàn)飛的接口岭粤。)

如何解決:繼承或依賴(推薦)。

關(guān)鍵代碼:適配器繼承或依賴已有的對(duì)象特笋,實(shí)現(xiàn)想要的目標(biāo)接口剃浇。

應(yīng)用實(shí)例: 1、美國(guó)電器 110V猎物,中國(guó) 220V虎囚,就要有一個(gè)適配器將 110V 轉(zhuǎn)化為 220V。 2蔫磨、JAVA JDK 1.1 提供了 Enumeration 接口淘讥,而在 1.2 中提供了 Iterator 接口,想要使用 1.2 的 JDK质帅,則要將以前系統(tǒng)的 Enumeration 接口轉(zhuǎn)化為 Iterator 接口适揉,這時(shí)就需要適配器模式。 3嫉嘀、在 LINUX 上運(yùn)行 WINDOWS 程序瓣俯。 4、JAVA 中的 jdbc宙攻。

優(yōu)點(diǎn): 1萍虽、可以讓任何兩個(gè)沒(méi)有關(guān)聯(lián)的類(lèi)一起運(yùn)行。 2改览、提高了類(lèi)的復(fù)用跌穗。 3奕枢、增加了類(lèi)的透明度族购。 4只盹、靈活性好。

缺點(diǎn): 1珊肃、過(guò)多地使用適配器,會(huì)讓系統(tǒng)非常零亂妇拯,不易整體進(jìn)行把握德撬。比如,明明看到調(diào)用的是 A 接口司训,其實(shí)內(nèi)部被適配成了 B 接口的實(shí)現(xiàn)勾徽,一個(gè)系統(tǒng)如果太多出現(xiàn)這種情況,無(wú)異于一場(chǎng)災(zāi)難统扳。因此如果不是很有必要喘帚,可以不使用適配器,而是直接對(duì)系統(tǒng)進(jìn)行重構(gòu)咒钟。 2.由于 JAVA 至多繼承一個(gè)類(lèi)吹由,所以至多只能適配一個(gè)適配者類(lèi),而且目標(biāo)類(lèi)必須是抽象類(lèi)朱嘴。

使用場(chǎng)景:有動(dòng)機(jī)地修改一個(gè)正常運(yùn)行的系統(tǒng)的接口倾鲫,這時(shí)應(yīng)該考慮使用適配器模式。

注意事項(xiàng):適配器不是在詳細(xì)設(shè)計(jì)時(shí)添加的,而是解決正在服役的項(xiàng)目的問(wèn)題级乍。


QQ截圖20200520153927.png

橋接模式

橋接(Bridge)是用于把抽象化與實(shí)現(xiàn)化解耦,使得二者可以獨(dú)立變化帚湘。這種類(lèi)型的設(shè)計(jì)模式屬于結(jié)構(gòu)型模式玫荣,它通過(guò)提供抽象化和實(shí)現(xiàn)化之間的橋接結(jié)構(gòu),來(lái)實(shí)現(xiàn)二者的解耦大诸。

這種模式涉及到一個(gè)作為橋接的接口捅厂,使得實(shí)體類(lèi)的功能獨(dú)立于接口實(shí)現(xiàn)類(lèi)。這兩種類(lèi)型的類(lèi)可被結(jié)構(gòu)化改變而互不影響资柔。

我們通過(guò)下面的實(shí)例來(lái)演示橋接模式(Bridge Pattern)的用法焙贷。其中,可以使用相同的抽象類(lèi)方法但是不同的橋接實(shí)現(xiàn)類(lèi)贿堰,來(lái)畫(huà)出不同顏色的圓辙芍。

介紹
意圖:將抽象部分與實(shí)現(xiàn)部分分離,使它們都可以獨(dú)立的變化羹与。

主要解決:在有多種可能會(huì)變化的情況下故硅,用繼承會(huì)造成類(lèi)爆炸問(wèn)題,擴(kuò)展起來(lái)不靈活纵搁。

何時(shí)使用:實(shí)現(xiàn)系統(tǒng)可能有多個(gè)角度分類(lèi)吃衅,每一種角度都可能變化。

如何解決:把這種多角度分類(lèi)分離出來(lái)腾誉,讓它們獨(dú)立變化徘层,減少它們之間耦合。

關(guān)鍵代碼:抽象類(lèi)依賴實(shí)現(xiàn)類(lèi)利职。

應(yīng)用實(shí)例: 1趣效、豬八戒從天蓬元帥轉(zhuǎn)世投胎到豬,轉(zhuǎn)世投胎的機(jī)制將塵世劃分為兩個(gè)等級(jí)猪贪,即:靈魂和肉體英支,前者相當(dāng)于抽象化,后者相當(dāng)于實(shí)現(xiàn)化哮伟。生靈通過(guò)功能的委派干花,調(diào)用肉體對(duì)象的功能,使得生靈可以動(dòng)態(tài)地選擇楞黄。 2池凄、墻上的開(kāi)關(guān),可以看到的開(kāi)關(guān)是抽象的鬼廓,不用管里面具體怎么實(shí)現(xiàn)的肿仑。

優(yōu)點(diǎn): 1、抽象和實(shí)現(xiàn)的分離。 2尤慰、優(yōu)秀的擴(kuò)展能力馏锡。 3、實(shí)現(xiàn)細(xì)節(jié)對(duì)客戶透明伟端。

缺點(diǎn):橋接模式的引入會(huì)增加系統(tǒng)的理解與設(shè)計(jì)難度杯道,由于聚合關(guān)聯(lián)關(guān)系建立在抽象層,要求開(kāi)發(fā)者針對(duì)抽象進(jìn)行設(shè)計(jì)與編程责蝠。

使用場(chǎng)景: 1党巾、如果一個(gè)系統(tǒng)需要在構(gòu)件的抽象化角色和具體化角色之間增加更多的靈活性擂橘,避免在兩個(gè)層次之間建立靜態(tài)的繼承聯(lián)系蕾管,通過(guò)橋接模式可以使它們?cè)诔橄髮咏⒁粋€(gè)關(guān)聯(lián)關(guān)系。 2孩等、對(duì)于那些不希望使用繼承或因?yàn)槎鄬哟卫^承導(dǎo)致系統(tǒng)類(lèi)的個(gè)數(shù)急劇增加的系統(tǒng)肴敛,橋接模式尤為適用署海。 3、一個(gè)類(lèi)存在兩個(gè)獨(dú)立變化的維度医男,且這兩個(gè)維度都需要進(jìn)行擴(kuò)展叹侄。

注意事項(xiàng):對(duì)于兩個(gè)獨(dú)立變化的維度,使用橋接模式再適合不過(guò)了昨登。


QQ截圖20200520154013.png

過(guò)濾器模式

過(guò)濾器模式(Filter Pattern)或標(biāo)準(zhǔn)模式(Criteria Pattern)是一種設(shè)計(jì)模式趾代,這種模式允許開(kāi)發(fā)人員使用不同的標(biāo)準(zhǔn)來(lái)過(guò)濾一組對(duì)象,通過(guò)邏輯運(yùn)算以解耦的方式把它們連接起來(lái)丰辣。這種類(lèi)型的設(shè)計(jì)模式屬于結(jié)構(gòu)型模式撒强,它結(jié)合多個(gè)標(biāo)準(zhǔn)來(lái)獲得單一標(biāo)準(zhǔn)。

實(shí)現(xiàn)
我們將創(chuàng)建一個(gè) Person 對(duì)象笙什、Criteria 接口和實(shí)現(xiàn)了該接口的實(shí)體類(lèi)飘哨,來(lái)過(guò)濾 Person 對(duì)象的列表。CriteriaPatternDemo琐凭,我們的演示類(lèi)使用 Criteria 對(duì)象芽隆,基于各種標(biāo)準(zhǔn)和它們的結(jié)合來(lái)過(guò)濾 Person 對(duì)象的列表。


QQ截圖20200520154055.png

組合模式

組合模式(Composite Pattern)统屈,又叫部分整體模式胚吁,是用于把一組相似的對(duì)象當(dāng)作一個(gè)單一的對(duì)象。組合模式依據(jù)樹(shù)形結(jié)構(gòu)來(lái)組合對(duì)象愁憔,用來(lái)表示部分以及整體層次腕扶。這種類(lèi)型的設(shè)計(jì)模式屬于結(jié)構(gòu)型模式,它創(chuàng)建了對(duì)象組的樹(shù)形結(jié)構(gòu)吨掌。

這種模式創(chuàng)建了一個(gè)包含自己對(duì)象組的類(lèi)半抱。該類(lèi)提供了修改相同對(duì)象組的方式脓恕。

我們通過(guò)下面的實(shí)例來(lái)演示組合模式的用法。實(shí)例演示了一個(gè)組織中員工的層次結(jié)構(gòu)窿侈。

介紹
意圖:將對(duì)象組合成樹(shù)形結(jié)構(gòu)以表示"部分-整體"的層次結(jié)構(gòu)炼幔。組合模式使得用戶對(duì)單個(gè)對(duì)象和組合對(duì)象的使用具有一致性。

主要解決:它在我們樹(shù)型結(jié)構(gòu)的問(wèn)題中史简,模糊了簡(jiǎn)單元素和復(fù)雜元素的概念乃秀,客戶程序可以像處理簡(jiǎn)單元素一樣來(lái)處理復(fù)雜元素,從而使得客戶程序與復(fù)雜元素的內(nèi)部結(jié)構(gòu)解耦乘瓤。

何時(shí)使用: 1环形、您想表示對(duì)象的部分-整體層次結(jié)構(gòu)(樹(shù)形結(jié)構(gòu))策泣。 2衙傀、您希望用戶忽略組合對(duì)象與單個(gè)對(duì)象的不同,用戶將統(tǒng)一地使用組合結(jié)構(gòu)中的所有對(duì)象萨咕。

如何解決:樹(shù)枝和葉子實(shí)現(xiàn)統(tǒng)一接口统抬,樹(shù)枝內(nèi)部組合該接口。

關(guān)鍵代碼:樹(shù)枝內(nèi)部組合該接口危队,并且含有內(nèi)部屬性 List聪建,里面放 Component。

應(yīng)用實(shí)例: 1茫陆、算術(shù)表達(dá)式包括操作數(shù)金麸、操作符和另一個(gè)操作數(shù),其中簿盅,另一個(gè)操作符也可以是操作數(shù)挥下、操作符和另一個(gè)操作數(shù)。 2桨醋、在 JAVA AWT 和 SWING 中棚瘟,對(duì)于 Button 和 Checkbox 是樹(shù)葉,Container 是樹(shù)枝喜最。

優(yōu)點(diǎn): 1偎蘸、高層模塊調(diào)用簡(jiǎn)單。 2瞬内、節(jié)點(diǎn)自由增加迷雪。

缺點(diǎn):在使用組合模式時(shí),其葉子和樹(shù)枝的聲明都是實(shí)現(xiàn)類(lèi)虫蝶,而不是接口振乏,違反了依賴倒置原則。

使用場(chǎng)景:部分秉扑、整體場(chǎng)景慧邮,如樹(shù)形菜單调限,文件、文件夾的管理误澳。

注意事項(xiàng):定義時(shí)為具體類(lèi)耻矮。


QQ截圖20200520154128.png

裝飾器模式

裝飾器模式(Decorator Pattern)允許向一個(gè)現(xiàn)有的對(duì)象添加新的功能,同時(shí)又不改變其結(jié)構(gòu)忆谓。這種類(lèi)型的設(shè)計(jì)模式屬于結(jié)構(gòu)型模式裆装,它是作為現(xiàn)有的類(lèi)的一個(gè)包裝。

這種模式創(chuàng)建了一個(gè)裝飾類(lèi)倡缠,用來(lái)包裝原有的類(lèi)哨免,并在保持類(lèi)方法簽名完整性的前提下,提供了額外的功能昙沦。

我們通過(guò)下面的實(shí)例來(lái)演示裝飾器模式的用法琢唾。其中,我們將把一個(gè)形狀裝飾上不同的顏色盾饮,同時(shí)又不改變形狀類(lèi)采桃。

介紹
意圖:動(dòng)態(tài)地給一個(gè)對(duì)象添加一些額外的職責(zé)。就增加功能來(lái)說(shuō)丘损,裝飾器模式相比生成子類(lèi)更為靈活普办。

主要解決:一般的,我們?yōu)榱藬U(kuò)展一個(gè)類(lèi)經(jīng)常使用繼承方式實(shí)現(xiàn)徘钥,由于繼承為類(lèi)引入靜態(tài)特征衔蹲,并且隨著擴(kuò)展功能的增多,子類(lèi)會(huì)很膨脹呈础。

何時(shí)使用:在不想增加很多子類(lèi)的情況下擴(kuò)展類(lèi)舆驶。

如何解決:將具體功能職責(zé)劃分,同時(shí)繼承裝飾者模式猪落。

關(guān)鍵代碼: 1贞远、Component 類(lèi)充當(dāng)抽象角色,不應(yīng)該具體實(shí)現(xiàn)笨忌。 2蓝仲、修飾類(lèi)引用和繼承 Component 類(lèi),具體擴(kuò)展類(lèi)重寫(xiě)父類(lèi)方法官疲。

應(yīng)用實(shí)例: 1袱结、孫悟空有 72 變,當(dāng)他變成"廟宇"后途凫,他的根本還是一只猴子垢夹,但是他又有了廟宇的功能。 2维费、不論一幅畫(huà)有沒(méi)有畫(huà)框都可以掛在墻上果元,但是通常都是有畫(huà)框的促王,并且實(shí)際上是畫(huà)框被掛在墻上。在掛在墻上之前而晒,畫(huà)可以被蒙上玻璃蝇狼,裝到框子里;這時(shí)畫(huà)倡怎、玻璃和畫(huà)框形成了一個(gè)物體迅耘。

優(yōu)點(diǎn):裝飾類(lèi)和被裝飾類(lèi)可以獨(dú)立發(fā)展,不會(huì)相互耦合监署,裝飾模式是繼承的一個(gè)替代模式颤专,裝飾模式可以動(dòng)態(tài)擴(kuò)展一個(gè)實(shí)現(xiàn)類(lèi)的功能。

缺點(diǎn):多層裝飾比較復(fù)雜钠乏。

使用場(chǎng)景: 1栖秕、擴(kuò)展一個(gè)類(lèi)的功能。 2缓熟、動(dòng)態(tài)增加功能累魔,動(dòng)態(tài)撤銷(xiāo)摔笤。

注意事項(xiàng):可代替繼承够滑。


QQ截圖20200520154245.png

外觀模式

外觀模式(Facade Pattern)隱藏系統(tǒng)的復(fù)雜性,并向客戶端提供了一個(gè)客戶端可以訪問(wèn)系統(tǒng)的接口吕世。這種類(lèi)型的設(shè)計(jì)模式屬于結(jié)構(gòu)型模式彰触,它向現(xiàn)有的系統(tǒng)添加一個(gè)接口,來(lái)隱藏系統(tǒng)的復(fù)雜性命辖。

這種模式涉及到一個(gè)單一的類(lèi)况毅,該類(lèi)提供了客戶端請(qǐng)求的簡(jiǎn)化方法和對(duì)現(xiàn)有系統(tǒng)類(lèi)方法的委托調(diào)用。

介紹
意圖:為子系統(tǒng)中的一組接口提供一個(gè)一致的界面尔艇,外觀模式定義了一個(gè)高層接口尔许,這個(gè)接口使得這一子系統(tǒng)更加容易使用。

主要解決:降低訪問(wèn)復(fù)雜系統(tǒng)的內(nèi)部子系統(tǒng)時(shí)的復(fù)雜度终娃,簡(jiǎn)化客戶端與之的接口味廊。

何時(shí)使用: 1、客戶端不需要知道系統(tǒng)內(nèi)部的復(fù)雜聯(lián)系棠耕,整個(gè)系統(tǒng)只需提供一個(gè)"接待員"即可余佛。 2、定義系統(tǒng)的入口窍荧。

如何解決:客戶端不與系統(tǒng)耦合辉巡,外觀類(lèi)與系統(tǒng)耦合。

關(guān)鍵代碼:在客戶端和復(fù)雜系統(tǒng)之間再加一層蕊退,這一層將調(diào)用順序郊楣、依賴關(guān)系等處理好憔恳。

應(yīng)用實(shí)例: 1、去醫(yī)院看病净蚤,可能要去掛號(hào)喇嘱、門(mén)診、劃價(jià)塞栅、取藥者铜,讓患者或患者家屬覺(jué)得很復(fù)雜,如果有提供接待人員放椰,只讓接待人員來(lái)處理作烟,就很方便。 2砾医、JAVA 的三層開(kāi)發(fā)模式拿撩。

優(yōu)點(diǎn): 1、減少系統(tǒng)相互依賴如蚜。 2压恒、提高靈活性。 3错邦、提高了安全性探赫。

缺點(diǎn):不符合開(kāi)閉原則,如果要改東西很麻煩撬呢,繼承重寫(xiě)都不合適伦吠。

使用場(chǎng)景: 1、為復(fù)雜的模塊或子系統(tǒng)提供外界訪問(wèn)的模塊魂拦。 2毛仪、子系統(tǒng)相對(duì)獨(dú)立。 3芯勘、預(yù)防低水平人員帶來(lái)的風(fēng)險(xiǎn)箱靴。

注意事項(xiàng):在層次化結(jié)構(gòu)中,可以使用外觀模式定義系統(tǒng)中每一層的入口荷愕。


QQ截圖20200520154316.png

享元模式

享元模式(Flyweight Pattern)主要用于減少創(chuàng)建對(duì)象的數(shù)量衡怀,以減少內(nèi)存占用和提高性能。這種類(lèi)型的設(shè)計(jì)模式屬于結(jié)構(gòu)型模式路翻,它提供了減少對(duì)象數(shù)量從而改善應(yīng)用所需的對(duì)象結(jié)構(gòu)的方式狈癞。

享元模式嘗試重用現(xiàn)有的同類(lèi)對(duì)象,如果未找到匹配的對(duì)象茂契,則創(chuàng)建新對(duì)象蝶桶。我們將通過(guò)創(chuàng)建 5 個(gè)對(duì)象來(lái)畫(huà)出 20 個(gè)分布于不同位置的圓來(lái)演示這種模式。由于只有 5 種可用的顏色掉冶,所以 color 屬性被用來(lái)檢查現(xiàn)有的 Circle 對(duì)象真竖。

介紹
意圖:運(yùn)用共享技術(shù)有效地支持大量細(xì)粒度的對(duì)象脐雪。

主要解決:在有大量對(duì)象時(shí),有可能會(huì)造成內(nèi)存溢出恢共,我們把其中共同的部分抽象出來(lái)战秋,如果有相同的業(yè)務(wù)請(qǐng)求,直接返回在內(nèi)存中已有的對(duì)象讨韭,避免重新創(chuàng)建脂信。

何時(shí)使用: 1、系統(tǒng)中有大量對(duì)象透硝。 2狰闪、這些對(duì)象消耗大量?jī)?nèi)存。 3濒生、這些對(duì)象的狀態(tài)大部分可以外部化埋泵。 4、這些對(duì)象可以按照內(nèi)蘊(yùn)狀態(tài)分為很多組罪治,當(dāng)把外蘊(yùn)對(duì)象從對(duì)象中剔除出來(lái)時(shí)丽声,每一組對(duì)象都可以用一個(gè)對(duì)象來(lái)代替。 5觉义、系統(tǒng)不依賴于這些對(duì)象身份雁社,這些對(duì)象是不可分辨的。

如何解決:用唯一標(biāo)識(shí)碼判斷谁撼,如果在內(nèi)存中有歧胁,則返回這個(gè)唯一標(biāo)識(shí)碼所標(biāo)識(shí)的對(duì)象滋饲。

關(guān)鍵代碼:用 HashMap 存儲(chǔ)這些對(duì)象厉碟。

應(yīng)用實(shí)例: 1、JAVA 中的 String屠缭,如果有則返回箍鼓,如果沒(méi)有則創(chuàng)建一個(gè)字符串保存在字符串緩存池里面。 2呵曹、數(shù)據(jù)庫(kù)的數(shù)據(jù)池款咖。

優(yōu)點(diǎn):大大減少對(duì)象的創(chuàng)建,降低系統(tǒng)的內(nèi)存奄喂,使效率提高铐殃。

缺點(diǎn):提高了系統(tǒng)的復(fù)雜度,需要分離出外部狀態(tài)和內(nèi)部狀態(tài)跨新,而且外部狀態(tài)具有固有化的性質(zhì)富腊,不應(yīng)該隨著內(nèi)部狀態(tài)的變化而變化,否則會(huì)造成系統(tǒng)的混亂域帐。

使用場(chǎng)景: 1赘被、系統(tǒng)有大量相似對(duì)象是整。 2、需要緩沖池的場(chǎng)景民假。

注意事項(xiàng): 1浮入、注意劃分外部狀態(tài)和內(nèi)部狀態(tài),否則可能會(huì)引起線程安全問(wèn)題羊异。 2事秀、這些類(lèi)必須有一個(gè)工廠對(duì)象加以控制。


QQ截圖20200520154351.png

代理模式

在代理模式(Proxy Pattern)中野舶,一個(gè)類(lèi)代表另一個(gè)類(lèi)的功能秽晚。這種類(lèi)型的設(shè)計(jì)模式屬于結(jié)構(gòu)型模式。

在代理模式中筒愚,我們創(chuàng)建具有現(xiàn)有對(duì)象的對(duì)象赴蝇,以便向外界提供功能接口。

介紹
意圖:為其他對(duì)象提供一種代理以控制對(duì)這個(gè)對(duì)象的訪問(wèn)巢掺。

主要解決:在直接訪問(wèn)對(duì)象時(shí)帶來(lái)的問(wèn)題句伶,比如說(shuō):要訪問(wèn)的對(duì)象在遠(yuǎn)程的機(jī)器上。在面向?qū)ο笙到y(tǒng)中陆淀,有些對(duì)象由于某些原因(比如對(duì)象創(chuàng)建開(kāi)銷(xiāo)很大考余,或者某些操作需要安全控制,或者需要進(jìn)程外的訪問(wèn))轧苫,直接訪問(wèn)會(huì)給使用者或者系統(tǒng)結(jié)構(gòu)帶來(lái)很多麻煩楚堤,我們可以在訪問(wèn)此對(duì)象時(shí)加上一個(gè)對(duì)此對(duì)象的訪問(wèn)層。

何時(shí)使用:想在訪問(wèn)一個(gè)類(lèi)時(shí)做一些控制含懊。

如何解決:增加中間層身冬。

關(guān)鍵代碼:實(shí)現(xiàn)與被代理類(lèi)組合。

應(yīng)用實(shí)例: 1岔乔、Windows 里面的快捷方式酥筝。 2、豬八戒去找高翠蘭結(jié)果是孫悟空變的雏门,可以這樣理解:把高翠蘭的外貌抽象出來(lái)嘿歌,高翠蘭本人和孫悟空都實(shí)現(xiàn)了這個(gè)接口,豬八戒訪問(wèn)高翠蘭的時(shí)候看不出來(lái)這個(gè)是孫悟空茁影,所以說(shuō)孫悟空是高翠蘭代理類(lèi)宙帝。 3、買(mǎi)火車(chē)票不一定在火車(chē)站買(mǎi)募闲,也可以去代售點(diǎn)步脓。 4、一張支票或銀行存單是賬戶中資金的代理。支票在市場(chǎng)交易中用來(lái)代替現(xiàn)金沪编,并提供對(duì)簽發(fā)人賬號(hào)上資金的控制呼盆。 5、spring aop蚁廓。

優(yōu)點(diǎn): 1访圃、職責(zé)清晰。 2相嵌、高擴(kuò)展性腿时。 3、智能化饭宾。

缺點(diǎn): 1批糟、由于在客戶端和真實(shí)主題之間增加了代理對(duì)象,因此有些類(lèi)型的代理模式可能會(huì)造成請(qǐng)求的處理速度變慢看铆。 2徽鼎、實(shí)現(xiàn)代理模式需要額外的工作,有些代理模式的實(shí)現(xiàn)非常復(fù)雜弹惦。

使用場(chǎng)景:按職責(zé)來(lái)劃分否淤,通常有以下使用場(chǎng)景: 1、遠(yuǎn)程代理棠隐。 2石抡、虛擬代理。 3助泽、Copy-on-Write 代理啰扛。 4、保護(hù)(Protect or Access)代理嗡贺。 5隐解、Cache代理。 6暑刃、防火墻(Firewall)代理厢漩。 7、同步化(Synchronization)代理岩臣。 8、智能引用(Smart Reference)代理宵膨。

注意事項(xiàng):
1架谎、和適配器模式的區(qū)別:適配器模式主要改變所考慮對(duì)象的接口,而代理模式不能改變所 代理類(lèi)的接口辟躏。
2谷扣、和裝飾器模式的區(qū)別:裝飾器模式為了增強(qiáng)功能,而代理模式是為了加以控制。


QQ截圖20200520154439.png

責(zé)任鏈模式

顧名思義会涎,責(zé)任鏈模式(Chain of Responsibility Pattern)為請(qǐng)求創(chuàng)建了一個(gè)接收者對(duì)象的鏈裹匙。這種模式給予請(qǐng)求的類(lèi)型,對(duì)請(qǐng)求的發(fā)送者和接收者進(jìn)行解耦末秃。這種類(lèi)型的設(shè)計(jì)模式屬于行為型模式概页。

在這種模式中,通常每個(gè)接收者都包含對(duì)另一個(gè)接收者的引用练慕。如果一個(gè)對(duì)象不能處理該請(qǐng)求惰匙,那么它會(huì)把相同的請(qǐng)求傳給下一個(gè)接收者,依此類(lèi)推铃将。

介紹
意圖:避免請(qǐng)求發(fā)送者與接收者耦合在一起项鬼,讓多個(gè)對(duì)象都有可能接收請(qǐng)求,將這些對(duì)象連接成一條鏈劲阎,并且沿著這條鏈傳遞請(qǐng)求绘盟,直到有對(duì)象處理它為止。

主要解決:職責(zé)鏈上的處理者負(fù)責(zé)處理請(qǐng)求悯仙,客戶只需要將請(qǐng)求發(fā)送到職責(zé)鏈上即可奥此,無(wú)須關(guān)心請(qǐng)求的處理細(xì)節(jié)和請(qǐng)求的傳遞,所以職責(zé)鏈將請(qǐng)求的發(fā)送者和請(qǐng)求的處理者解耦了雁比。

何時(shí)使用:在處理消息的時(shí)候以過(guò)濾很多道稚虎。

如何解決:攔截的類(lèi)都實(shí)現(xiàn)統(tǒng)一接口。

關(guān)鍵代碼:Handler 里面聚合它自己偎捎,在 HandlerRequest 里判斷是否合適蠢终,如果沒(méi)達(dá)到條件則向下傳遞,向誰(shuí)傳遞之前 set 進(jìn)去茴她。

應(yīng)用實(shí)例: 1寻拂、紅樓夢(mèng)中的"擊鼓傳花"。 2丈牢、JS 中的事件冒泡祭钉。 3、JAVA WEB 中 Apache Tomcat 對(duì) Encoding 的處理己沛,Struts2 的攔截器慌核,jsp servlet 的 Filter。

優(yōu)點(diǎn): 1申尼、降低耦合度垮卓。它將請(qǐng)求的發(fā)送者和接收者解耦。 2师幕、簡(jiǎn)化了對(duì)象粟按。使得對(duì)象不需要知道鏈的結(jié)構(gòu)。 3、增強(qiáng)給對(duì)象指派職責(zé)的靈活性灭将。通過(guò)改變鏈內(nèi)的成員或者調(diào)動(dòng)它們的次序疼鸟,允許動(dòng)態(tài)地新增或者刪除責(zé)任渴逻。 4伞辛、增加新的請(qǐng)求處理類(lèi)很方便陡舅。

缺點(diǎn): 1吮旅、不能保證請(qǐng)求一定被接收恩掷。 2尤揣、系統(tǒng)性能將受到一定影響糟秘,而且在進(jìn)行代碼調(diào)試時(shí)不太方便黔攒,可能會(huì)造成循環(huán)調(diào)用男旗。 3舶斧、可能不容易觀察運(yùn)行時(shí)的特征,有礙于除錯(cuò)察皇。

使用場(chǎng)景: 1茴厉、有多個(gè)對(duì)象可以處理同一個(gè)請(qǐng)求,具體哪個(gè)對(duì)象處理該請(qǐng)求由運(yùn)行時(shí)刻自動(dòng)確定什荣。 2矾缓、在不明確指定接收者的情況下,向多個(gè)對(duì)象中的一個(gè)提交一個(gè)請(qǐng)求稻爬。 3嗜闻、可動(dòng)態(tài)指定一組對(duì)象處理請(qǐng)求。

注意事項(xiàng):在 JAVA WEB 中遇到很多應(yīng)用桅锄。


QQ截圖20200520154509.png

命令模式

命令模式(Command Pattern)是一種數(shù)據(jù)驅(qū)動(dòng)的設(shè)計(jì)模式琉雳,它屬于行為型模式。請(qǐng)求以命令的形式包裹在對(duì)象中友瘤,并傳給調(diào)用對(duì)象翠肘。調(diào)用對(duì)象尋找可以處理該命令的合適的對(duì)象,并把該命令傳給相應(yīng)的對(duì)象辫秧,該對(duì)象執(zhí)行命令束倍。

介紹
意圖:將一個(gè)請(qǐng)求封裝成一個(gè)對(duì)象,從而使您可以用不同的請(qǐng)求對(duì)客戶進(jìn)行參數(shù)化盟戏。

主要解決:在軟件系統(tǒng)中绪妹,行為請(qǐng)求者與行為實(shí)現(xiàn)者通常是一種緊耦合的關(guān)系,但某些場(chǎng)合抓半,比如需要對(duì)行為進(jìn)行記錄喂急、撤銷(xiāo)或重做、事務(wù)等處理時(shí)笛求,這種無(wú)法抵御變化的緊耦合的設(shè)計(jì)就不太合適。

何時(shí)使用:在某些場(chǎng)合,比如要對(duì)行為進(jìn)行"記錄探入、撤銷(xiāo)/重做狡孔、事務(wù)"等處理,這種無(wú)法抵御變化的緊耦合是不合適的蜂嗽。在這種情況下苗膝,如何將"行為請(qǐng)求者"與"行為實(shí)現(xiàn)者"解耦?將一組行為抽象為對(duì)象植旧,可以實(shí)現(xiàn)二者之間的松耦合辱揭。

如何解決:通過(guò)調(diào)用者調(diào)用接受者執(zhí)行命令,順序:調(diào)用者→接受者→命令病附。

關(guān)鍵代碼:定義三個(gè)角色:1问窃、received 真正的命令執(zhí)行對(duì)象 2、Command 3完沪、invoker 使用命令對(duì)象的入口

應(yīng)用實(shí)例:struts 1 中的 action 核心控制器 ActionServlet 只有一個(gè)域庇,相當(dāng)于 Invoker,而模型層的類(lèi)會(huì)隨著不同的應(yīng)用有不同的模型類(lèi)覆积,相當(dāng)于具體的 Command听皿。

優(yōu)點(diǎn): 1、降低了系統(tǒng)耦合度宽档。 2尉姨、新的命令可以很容易添加到系統(tǒng)中去。

缺點(diǎn):使用命令模式可能會(huì)導(dǎo)致某些系統(tǒng)有過(guò)多的具體命令類(lèi)吗冤。

使用場(chǎng)景:認(rèn)為是命令的地方都可以使用命令模式又厉,比如: 1、GUI 中每一個(gè)按鈕都是一條命令欣孤。 2馋没、模擬 CMD。

注意事項(xiàng):系統(tǒng)需要支持命令的撤銷(xiāo)(Undo)操作和恢復(fù)(Redo)操作降传,也可以考慮使用命令模式篷朵,見(jiàn)命令模式的擴(kuò)展。


QQ截圖20200520154538.png

解釋器模式

解釋器模式(Interpreter Pattern)提供了評(píng)估語(yǔ)言的語(yǔ)法或表達(dá)式的方式婆排,它屬于行為型模式声旺。這種模式實(shí)現(xiàn)了一個(gè)表達(dá)式接口,該接口解釋一個(gè)特定的上下文段只。這種模式被用在 SQL 解析腮猖、符號(hào)處理引擎等。

介紹
意圖:給定一個(gè)語(yǔ)言赞枕,定義它的文法表示澈缺,并定義一個(gè)解釋器坪创,這個(gè)解釋器使用該標(biāo)識(shí)來(lái)解釋語(yǔ)言中的句子。

主要解決:對(duì)于一些固定文法構(gòu)建一個(gè)解釋句子的解釋器姐赡。

何時(shí)使用:如果一種特定類(lèi)型的問(wèn)題發(fā)生的頻率足夠高莱预,那么可能就值得將該問(wèn)題的各個(gè)實(shí)例表述為一個(gè)簡(jiǎn)單語(yǔ)言中的句子。這樣就可以構(gòu)建一個(gè)解釋器依沮,該解釋器通過(guò)解釋這些句子來(lái)解決該問(wèn)題。

如何解決:構(gòu)建語(yǔ)法樹(shù),定義終結(jié)符與非終結(jié)符谈飒。

關(guān)鍵代碼:構(gòu)建環(huán)境類(lèi),包含解釋器之外的一些全局信息邓嘹,一般是 HashMap棚贾。

應(yīng)用實(shí)例:編譯器、運(yùn)算表達(dá)式計(jì)算塘偎。

優(yōu)點(diǎn): 1椰憋、可擴(kuò)展性比較好,靈活赔退。 2橙依、增加了新的解釋表達(dá)式的方式。 3离钝、易于實(shí)現(xiàn)簡(jiǎn)單文法票编。

缺點(diǎn): 1、可利用場(chǎng)景比較少卵渴。 2慧域、對(duì)于復(fù)雜的文法比較難維護(hù)。 3浪读、解釋器模式會(huì)引起類(lèi)膨脹昔榴。 4辛藻、解釋器模式采用遞歸調(diào)用方法。

使用場(chǎng)景: 1互订、可以將一個(gè)需要解釋執(zhí)行的語(yǔ)言中的句子表示為一個(gè)抽象語(yǔ)法樹(shù)吱肌。 2、一些重復(fù)出現(xiàn)的問(wèn)題可以用一種簡(jiǎn)單的語(yǔ)言來(lái)進(jìn)行表達(dá)仰禽。 3氮墨、一個(gè)簡(jiǎn)單語(yǔ)法需要解釋的場(chǎng)景。

注意事項(xiàng):可利用場(chǎng)景比較少吐葵,JAVA 中如果碰到可以用 expression4J 代替规揪。


QQ截圖20200520154641.png

迭代器模式

迭代器模式(Iterator Pattern)是 Java 和 .Net 編程環(huán)境中非常常用的設(shè)計(jì)模式。這種模式用于順序訪問(wèn)集合對(duì)象的元素温峭,不需要知道集合對(duì)象的底層表示猛铅。

迭代器模式屬于行為型模式。

介紹
意圖:提供一種方法順序訪問(wèn)一個(gè)聚合對(duì)象中各個(gè)元素, 而又無(wú)須暴露該對(duì)象的內(nèi)部表示凤藏。

主要解決:不同的方式來(lái)遍歷整個(gè)整合對(duì)象奸忽。

何時(shí)使用:遍歷一個(gè)聚合對(duì)象。

如何解決:把在元素之間游走的責(zé)任交給迭代器揖庄,而不是聚合對(duì)象栗菜。

關(guān)鍵代碼:定義接口:hasNext, next。

應(yīng)用實(shí)例:JAVA 中的 iterator抠艾。

優(yōu)點(diǎn): 1苛萎、它支持以不同的方式遍歷一個(gè)聚合對(duì)象。 2检号、迭代器簡(jiǎn)化了聚合類(lèi)腌歉。 3、在同一個(gè)聚合上可以有多個(gè)遍歷齐苛。 4翘盖、在迭代器模式中,增加新的聚合類(lèi)和迭代器類(lèi)都很方便凹蜂,無(wú)須修改原有代碼馍驯。

缺點(diǎn):由于迭代器模式將存儲(chǔ)數(shù)據(jù)和遍歷數(shù)據(jù)的職責(zé)分離,增加新的聚合類(lèi)需要對(duì)應(yīng)增加新的迭代器類(lèi)玛痊,類(lèi)的個(gè)數(shù)成對(duì)增加汰瘫,這在一定程度上增加了系統(tǒng)的復(fù)雜性。

使用場(chǎng)景: 1擂煞、訪問(wèn)一個(gè)聚合對(duì)象的內(nèi)容而無(wú)須暴露它的內(nèi)部表示混弥。 2、需要為聚合對(duì)象提供多種遍歷方式对省。 3蝗拿、為遍歷不同的聚合結(jié)構(gòu)提供一個(gè)統(tǒng)一的接口晾捏。

注意事項(xiàng):迭代器模式就是分離了集合對(duì)象的遍歷行為,抽象出一個(gè)迭代器類(lèi)來(lái)負(fù)責(zé)哀托,這樣既可以做到不暴露集合的內(nèi)部結(jié)構(gòu)惦辛,又可讓外部代碼透明地訪問(wèn)集合內(nèi)部的數(shù)據(jù)。


QQ截圖20200520154713.png

中介者模式

中介者模式(Mediator Pattern)是用來(lái)降低多個(gè)對(duì)象和類(lèi)之間的通信復(fù)雜性仓手。這種模式提供了一個(gè)中介類(lèi)胖齐,該類(lèi)通常處理不同類(lèi)之間的通信,并支持松耦合俗或,使代碼易于維護(hù)市怎。中介者模式屬于行為型模式。

介紹
意圖:用一個(gè)中介對(duì)象來(lái)封裝一系列的對(duì)象交互辛慰,中介者使各對(duì)象不需要顯式地相互引用,從而使其耦合松散干像,而且可以獨(dú)立地改變它們之間的交互帅腌。

主要解決:對(duì)象與對(duì)象之間存在大量的關(guān)聯(lián)關(guān)系,這樣勢(shì)必會(huì)導(dǎo)致系統(tǒng)的結(jié)構(gòu)變得很復(fù)雜麻汰,同時(shí)若一個(gè)對(duì)象發(fā)生改變速客,我們也需要跟蹤與之相關(guān)聯(lián)的對(duì)象,同時(shí)做出相應(yīng)的處理五鲫。

何時(shí)使用:多個(gè)類(lèi)相互耦合溺职,形成了網(wǎng)狀結(jié)構(gòu)。

如何解決:將上述網(wǎng)狀結(jié)構(gòu)分離為星型結(jié)構(gòu)位喂。

關(guān)鍵代碼:對(duì)象 Colleague 之間的通信封裝到一個(gè)類(lèi)中單獨(dú)處理浪耘。

應(yīng)用實(shí)例: 1、中國(guó)加入 WTO 之前是各個(gè)國(guó)家相互貿(mào)易塑崖,結(jié)構(gòu)復(fù)雜七冲,現(xiàn)在是各個(gè)國(guó)家通過(guò) WTO 來(lái)互相貿(mào)易。 2规婆、機(jī)場(chǎng)調(diào)度系統(tǒng)澜躺。 3、MVC 框架抒蚜,其中C(控制器)就是 M(模型)和 V(視圖)的中介者掘鄙。

優(yōu)點(diǎn): 1、降低了類(lèi)的復(fù)雜度嗡髓,將一對(duì)多轉(zhuǎn)化成了一對(duì)一操漠。 2、各個(gè)類(lèi)之間的解耦器贩。 3颅夺、符合迪米特原則朋截。

缺點(diǎn):中介者會(huì)龐大,變得復(fù)雜難以維護(hù)吧黄。

使用場(chǎng)景: 1部服、系統(tǒng)中對(duì)象之間存在比較復(fù)雜的引用關(guān)系,導(dǎo)致它們之間的依賴關(guān)系結(jié)構(gòu)混亂而且難以復(fù)用該對(duì)象拗慨。 2廓八、想通過(guò)一個(gè)中間類(lèi)來(lái)封裝多個(gè)類(lèi)中的行為,而又不想生成太多的子類(lèi)赵抢。

注意事項(xiàng):不應(yīng)當(dāng)在職責(zé)混亂的時(shí)候使用剧蹂。


QQ截圖20200520154740.png

備忘錄模式

備忘錄模式(Memento Pattern)保存一個(gè)對(duì)象的某個(gè)狀態(tài),以便在適當(dāng)?shù)臅r(shí)候恢復(fù)對(duì)象烦却。備忘錄模式屬于行為型模式宠叼。

介紹
意圖:在不破壞封裝性的前提下,捕獲一個(gè)對(duì)象的內(nèi)部狀態(tài)其爵,并在該對(duì)象之外保存這個(gè)狀態(tài)冒冬。

主要解決:所謂備忘錄模式就是在不破壞封裝的前提下,捕獲一個(gè)對(duì)象的內(nèi)部狀態(tài)摩渺,并在該對(duì)象之外保存這個(gè)狀態(tài)简烤,這樣可以在以后將對(duì)象恢復(fù)到原先保存的狀態(tài)。

何時(shí)使用:很多時(shí)候我們總是需要記錄一個(gè)對(duì)象的內(nèi)部狀態(tài)摇幻,這樣做的目的就是為了允許用戶取消不確定或者錯(cuò)誤的操作横侦,能夠恢復(fù)到他原先的狀態(tài),使得他有"后悔藥"可吃绰姻。

如何解決:通過(guò)一個(gè)備忘錄類(lèi)專門(mén)存儲(chǔ)對(duì)象狀態(tài)枉侧。

關(guān)鍵代碼:客戶不與備忘錄類(lèi)耦合,與備忘錄管理類(lèi)耦合龙宏。

應(yīng)用實(shí)例: 1棵逊、后悔藥。 2银酗、打游戲時(shí)的存檔辆影。 3、Windows 里的 ctri + z黍特。 4蛙讥、IE 中的后退。 4灭衷、數(shù)據(jù)庫(kù)的事務(wù)管理次慢。

優(yōu)點(diǎn): 1、給用戶提供了一種可以恢復(fù)狀態(tài)的機(jī)制,可以使用戶能夠比較方便地回到某個(gè)歷史的狀態(tài)迫像。 2劈愚、實(shí)現(xiàn)了信息的封裝,使得用戶不需要關(guān)心狀態(tài)的保存細(xì)節(jié)闻妓。

缺點(diǎn):消耗資源菌羽。如果類(lèi)的成員變量過(guò)多,勢(shì)必會(huì)占用比較大的資源由缆,而且每一次保存都會(huì)消耗一定的內(nèi)存注祖。

使用場(chǎng)景: 1、需要保存/恢復(fù)數(shù)據(jù)的相關(guān)狀態(tài)場(chǎng)景均唉。 2是晨、提供一個(gè)可回滾的操作。

注意事項(xiàng): 1舔箭、為了符合迪米特原則罩缴,還要增加一個(gè)管理備忘錄的類(lèi)。 2限嫌、為了節(jié)約內(nèi)存靴庆,可使用原型模式+備忘錄模式。


QQ截圖20200520154850.png

觀察者模式

當(dāng)對(duì)象間存在一對(duì)多關(guān)系時(shí)怒医,則使用觀察者模式(Observer Pattern)。比如奢讨,當(dāng)一個(gè)對(duì)象被修改時(shí)稚叹,則會(huì)自動(dòng)通知它的依賴對(duì)象。觀察者模式屬于行為型模式拿诸。

介紹
意圖:定義對(duì)象間的一種一對(duì)多的依賴關(guān)系扒袖,當(dāng)一個(gè)對(duì)象的狀態(tài)發(fā)生改變時(shí),所有依賴于它的對(duì)象都得到通知并被自動(dòng)更新亩码。

主要解決:一個(gè)對(duì)象狀態(tài)改變給其他對(duì)象通知的問(wèn)題季率,而且要考慮到易用和低耦合,保證高度的協(xié)作描沟。

何時(shí)使用:一個(gè)對(duì)象(目標(biāo)對(duì)象)的狀態(tài)發(fā)生改變飒泻,所有的依賴對(duì)象(觀察者對(duì)象)都將得到通知,進(jìn)行廣播通知吏廉。

如何解決:使用面向?qū)ο蠹夹g(shù)泞遗,可以將這種依賴關(guān)系弱化。

關(guān)鍵代碼:在抽象類(lèi)里有一個(gè) ArrayList 存放觀察者們席覆。

應(yīng)用實(shí)例: 1史辙、拍賣(mài)的時(shí)候,拍賣(mài)師觀察最高標(biāo)價(jià),然后通知給其他競(jìng)價(jià)者競(jìng)價(jià)聊倔。 2晦毙、西游記里面悟空請(qǐng)求菩薩降服紅孩兒,菩薩灑了一地水招來(lái)一個(gè)老烏龜耙蔑,這個(gè)烏龜就是觀察者见妒,他觀察菩薩灑水這個(gè)動(dòng)作。

優(yōu)點(diǎn): 1纵潦、觀察者和被觀察者是抽象耦合的徐鹤。 2、建立一套觸發(fā)機(jī)制邀层。

缺點(diǎn): 1返敬、如果一個(gè)被觀察者對(duì)象有很多的直接和間接的觀察者的話,將所有的觀察者都通知到會(huì)花費(fèi)很多時(shí)間寥院。 2劲赠、如果在觀察者和觀察目標(biāo)之間有循環(huán)依賴的話,觀察目標(biāo)會(huì)觸發(fā)它們之間進(jìn)行循環(huán)調(diào)用秸谢,可能導(dǎo)致系統(tǒng)崩潰凛澎。 3、觀察者模式?jīng)]有相應(yīng)的機(jī)制讓觀察者知道所觀察的目標(biāo)對(duì)象是怎么發(fā)生變化的估蹄,而僅僅只是知道觀察目標(biāo)發(fā)生了變化塑煎。

使用場(chǎng)景:

一個(gè)抽象模型有兩個(gè)方面,其中一個(gè)方面依賴于另一個(gè)方面臭蚁。將這些方面封裝在獨(dú)立的對(duì)象中使它們可以各自獨(dú)立地改變和復(fù)用最铁。
一個(gè)對(duì)象的改變將導(dǎo)致其他一個(gè)或多個(gè)對(duì)象也發(fā)生改變,而不知道具體有多少對(duì)象將發(fā)生改變垮兑,可以降低對(duì)象之間的耦合度冷尉。
一個(gè)對(duì)象必須通知其他對(duì)象,而并不知道這些對(duì)象是誰(shuí)系枪。
需要在系統(tǒng)中創(chuàng)建一個(gè)觸發(fā)鏈雀哨,A對(duì)象的行為將影響B(tài)對(duì)象,B對(duì)象的行為將影響C對(duì)象……私爷,可以使用觀察者模式創(chuàng)建一種鏈?zhǔn)接|發(fā)機(jī)制雾棺。
注意事項(xiàng):
1、JAVA 中已經(jīng)有了對(duì)觀察者模式的支持類(lèi)当犯。
2垢村、避免循環(huán)引用。
3嚎卫、如果順序執(zhí)行嘉栓,某一觀察者錯(cuò)誤會(huì)導(dǎo)致系統(tǒng)卡殼宏榕,一般采用異步方式。


QQ截圖20200520154933.png

狀態(tài)模式

在狀態(tài)模式(State Pattern)中侵佃,類(lèi)的行為是基于它的狀態(tài)改變的麻昼。這種類(lèi)型的設(shè)計(jì)模式屬于行為型模式。

在狀態(tài)模式中馋辈,我們創(chuàng)建表示各種狀態(tài)的對(duì)象和一個(gè)行為隨著狀態(tài)對(duì)象改變而改變的 context 對(duì)象抚芦。

介紹
意圖:允許對(duì)象在內(nèi)部狀態(tài)發(fā)生改變時(shí)改變它的行為,對(duì)象看起來(lái)好像修改了它的類(lèi)迈螟。

主要解決:對(duì)象的行為依賴于它的狀態(tài)(屬性)叉抡,并且可以根據(jù)它的狀態(tài)改變而改變它的相關(guān)行為。

何時(shí)使用:代碼中包含大量與對(duì)象狀態(tài)有關(guān)的條件語(yǔ)句答毫。

如何解決:將各種具體的狀態(tài)類(lèi)抽象出來(lái)褥民。

關(guān)鍵代碼:通常命令模式的接口中只有一個(gè)方法。而狀態(tài)模式的接口中有一個(gè)或者多個(gè)方法洗搂。而且消返,狀態(tài)模式的實(shí)現(xiàn)類(lèi)的方法,一般返回值耘拇,或者是改變實(shí)例變量的值撵颊。也就是說(shuō),狀態(tài)模式一般和對(duì)象的狀態(tài)有關(guān)惫叛。實(shí)現(xiàn)類(lèi)的方法有不同的功能倡勇,覆蓋接口中的方法。狀態(tài)模式和命令模式一樣嘉涌,也可以用于消除 if...else 等條件選擇語(yǔ)句译隘。

應(yīng)用實(shí)例: 1、打籃球的時(shí)候運(yùn)動(dòng)員可以有正常狀態(tài)洛心、不正常狀態(tài)和超常狀態(tài)。 2题篷、曾侯乙編鐘中词身,'鐘是抽象接口','鐘A'等是具體狀態(tài),'曾侯乙編鐘'是具體環(huán)境(Context)番枚。

優(yōu)點(diǎn): 1法严、封裝了轉(zhuǎn)換規(guī)則。 2葫笼、枚舉可能的狀態(tài)深啤,在枚舉狀態(tài)之前需要確定狀態(tài)種類(lèi)。 3路星、將所有與某個(gè)狀態(tài)有關(guān)的行為放到一個(gè)類(lèi)中溯街,并且可以方便地增加新的狀態(tài),只需要改變對(duì)象狀態(tài)即可改變對(duì)象的行為。 4呈昔、允許狀態(tài)轉(zhuǎn)換邏輯與狀態(tài)對(duì)象合成一體挥等,而不是某一個(gè)巨大的條件語(yǔ)句塊。 5堤尾、可以讓多個(gè)環(huán)境對(duì)象共享一個(gè)狀態(tài)對(duì)象肝劲,從而減少系統(tǒng)中對(duì)象的個(gè)數(shù)。

缺點(diǎn): 1郭宝、狀態(tài)模式的使用必然會(huì)增加系統(tǒng)類(lèi)和對(duì)象的個(gè)數(shù)辞槐。 2、狀態(tài)模式的結(jié)構(gòu)與實(shí)現(xiàn)都較為復(fù)雜粘室,如果使用不當(dāng)將導(dǎo)致程序結(jié)構(gòu)和代碼的混亂榄檬。 3、狀態(tài)模式對(duì)"開(kāi)閉原則"的支持并不太好育特,對(duì)于可以切換狀態(tài)的狀態(tài)模式丙号,增加新的狀態(tài)類(lèi)需要修改那些負(fù)責(zé)狀態(tài)轉(zhuǎn)換的源代碼,否則無(wú)法切換到新增狀態(tài)缰冤,而且修改某個(gè)狀態(tài)類(lèi)的行為也需修改對(duì)應(yīng)類(lèi)的源代碼犬缨。

使用場(chǎng)景: 1、行為隨狀態(tài)改變而改變的場(chǎng)景棉浸。 2怀薛、條件、分支語(yǔ)句的代替者迷郑。

注意事項(xiàng):在行為受狀態(tài)約束的時(shí)候使用狀態(tài)模式枝恋,而且狀態(tài)不超過(guò) 5 個(gè)。


QQ截圖20200520155054.png

空對(duì)象模式
在空對(duì)象模式(Null Object Pattern)中嗡害,一個(gè)空對(duì)象取代 NULL 對(duì)象實(shí)例的檢查焚碌。Null 對(duì)象不是檢查空值,而是反應(yīng)一個(gè)不做任何動(dòng)作的關(guān)系霸妹。這樣的 Null 對(duì)象也可以在數(shù)據(jù)不可用的時(shí)候提供默認(rèn)的行為十电。

在空對(duì)象模式中,我們創(chuàng)建一個(gè)指定各種要執(zhí)行的操作的抽象類(lèi)和擴(kuò)展該類(lèi)的實(shí)體類(lèi)叹螟,還創(chuàng)建一個(gè)未對(duì)該類(lèi)做任何實(shí)現(xiàn)的空對(duì)象類(lèi)鹃骂,該空對(duì)象類(lèi)將無(wú)縫地使用在需要檢查空值的地方。


QQ截圖20200520155127.png

策略模式

在策略模式(Strategy Pattern)中罢绽,一個(gè)類(lèi)的行為或其算法可以在運(yùn)行時(shí)更改畏线。這種類(lèi)型的設(shè)計(jì)模式屬于行為型模式。

在策略模式中良价,我們創(chuàng)建表示各種策略的對(duì)象和一個(gè)行為隨著策略對(duì)象改變而改變的 context 對(duì)象寝殴。策略對(duì)象改變 context 對(duì)象的執(zhí)行算法蒿叠。

介紹
意圖:定義一系列的算法,把它們一個(gè)個(gè)封裝起來(lái), 并且使它們可相互替換。

主要解決:在有多種算法相似的情況下杯矩,使用 if...else 所帶來(lái)的復(fù)雜和難以維護(hù)栈虚。

何時(shí)使用:一個(gè)系統(tǒng)有許多許多類(lèi)讥此,而區(qū)分它們的只是他們直接的行為炬太。

如何解決:將這些算法封裝成一個(gè)一個(gè)的類(lèi),任意地替換考阱。

關(guān)鍵代碼:實(shí)現(xiàn)同一個(gè)接口泌射。

應(yīng)用實(shí)例: 1粘姜、諸葛亮的錦囊妙計(jì),每一個(gè)錦囊就是一個(gè)策略熔酷。 2孤紧、旅行的出游方式,選擇騎自行車(chē)拒秘、坐汽車(chē)号显,每一種旅行方式都是一個(gè)策略。 3躺酒、JAVA AWT 中的 LayoutManager押蚤。

優(yōu)點(diǎn): 1、算法可以自由切換羹应。 2揽碘、避免使用多重條件判斷。 3园匹、擴(kuò)展性良好雳刺。

缺點(diǎn): 1、策略類(lèi)會(huì)增多裸违。 2掖桦、所有策略類(lèi)都需要對(duì)外暴露。

使用場(chǎng)景: 1供汛、如果在一個(gè)系統(tǒng)里面有許多類(lèi)滞详,它們之間的區(qū)別僅在于它們的行為,那么使用策略模式可以動(dòng)態(tài)地讓一個(gè)對(duì)象在許多行為中選擇一種行為紊馏。 2、一個(gè)系統(tǒng)需要?jiǎng)討B(tài)地在幾種算法中選擇一種蒲犬。 3朱监、如果一個(gè)對(duì)象有很多的行為,如果不用恰當(dāng)?shù)哪J皆#@些行為就只好使用多重的條件選擇語(yǔ)句來(lái)實(shí)現(xiàn)赫编。

注意事項(xiàng):如果一個(gè)系統(tǒng)的策略多于四個(gè)巡蘸,就需要考慮使用混合模式,解決策略類(lèi)膨脹的問(wèn)題擂送。


QQ截圖20200520155156.png

模板模式

在模板模式(Template Pattern)中悦荒,一個(gè)抽象類(lèi)公開(kāi)定義了執(zhí)行它的方法的方式/模板。它的子類(lèi)可以按需要重寫(xiě)方法實(shí)現(xiàn)嘹吨,但調(diào)用將以抽象類(lèi)中定義的方式進(jìn)行搬味。這種類(lèi)型的設(shè)計(jì)模式屬于行為型模式。

介紹
意圖:定義一個(gè)操作中的算法的骨架蟀拷,而將一些步驟延遲到子類(lèi)中碰纬。模板方法使得子類(lèi)可以不改變一個(gè)算法的結(jié)構(gòu)即可重定義該算法的某些特定步驟。

主要解決:一些方法通用问芬,卻在每一個(gè)子類(lèi)都重新寫(xiě)了這一方法悦析。

何時(shí)使用:有一些通用的方法。

如何解決:將這些通用算法抽象出來(lái)此衅。

關(guān)鍵代碼:在抽象類(lèi)實(shí)現(xiàn)强戴,其他步驟在子類(lèi)實(shí)現(xiàn)。

應(yīng)用實(shí)例: 1挡鞍、在造房子的時(shí)候骑歹,地基、走線匕累、水管都一樣陵刹,只有在建筑的后期才有加壁櫥加?xùn)艡诘炔町悺?2、西游記里面菩薩定好的 81 難欢嘿,這就是一個(gè)頂層的邏輯骨架衰琐。 3、spring 中對(duì) Hibernate 的支持炼蹦,將一些已經(jīng)定好的方法封裝起來(lái)羡宙,比如開(kāi)啟事務(wù)、獲取 Session掐隐、關(guān)閉 Session 等狗热,程序員不重復(fù)寫(xiě)那些已經(jīng)規(guī)范好的代碼,直接丟一個(gè)實(shí)體就可以保存虑省。

優(yōu)點(diǎn): 1匿刮、封裝不變部分,擴(kuò)展可變部分探颈。 2熟丸、提取公共代碼,便于維護(hù)伪节。 3光羞、行為由父類(lèi)控制绩鸣,子類(lèi)實(shí)現(xiàn)。

缺點(diǎn):每一個(gè)不同的實(shí)現(xiàn)都需要一個(gè)子類(lèi)來(lái)實(shí)現(xiàn)纱兑,導(dǎo)致類(lèi)的個(gè)數(shù)增加呀闻,使得系統(tǒng)更加龐大。

使用場(chǎng)景: 1潜慎、有多個(gè)子類(lèi)共有的方法捡多,且邏輯相同。 2勘纯、重要的局服、復(fù)雜的方法,可以考慮作為模板方法驳遵。

注意事項(xiàng):為防止惡意操作淫奔,一般模板方法都加上 final 關(guān)鍵詞。


QQ截圖20200520155228.png

訪問(wèn)者模式

在訪問(wèn)者模式(Visitor Pattern)中堤结,我們使用了一個(gè)訪問(wèn)者類(lèi)唆迁,它改變了元素類(lèi)的執(zhí)行算法。通過(guò)這種方式竞穷,元素的執(zhí)行算法可以隨著訪問(wèn)者改變而改變唐责。這種類(lèi)型的設(shè)計(jì)模式屬于行為型模式。根據(jù)模式瘾带,元素對(duì)象已接受訪問(wèn)者對(duì)象鼠哥,這樣訪問(wèn)者對(duì)象就可以處理元素對(duì)象上的操作。

介紹
意圖:主要將數(shù)據(jù)結(jié)構(gòu)與數(shù)據(jù)操作分離看政。

主要解決:穩(wěn)定的數(shù)據(jù)結(jié)構(gòu)和易變的操作耦合問(wèn)題朴恳。

何時(shí)使用:需要對(duì)一個(gè)對(duì)象結(jié)構(gòu)中的對(duì)象進(jìn)行很多不同的并且不相關(guān)的操作,而需要避免讓這些操作"污染"這些對(duì)象的類(lèi)允蚣,使用訪問(wèn)者模式將這些封裝到類(lèi)中于颖。

如何解決:在被訪問(wèn)的類(lèi)里面加一個(gè)對(duì)外提供接待訪問(wèn)者的接口。

關(guān)鍵代碼:在數(shù)據(jù)基礎(chǔ)類(lèi)里面有一個(gè)方法接受訪問(wèn)者嚷兔,將自身引用傳入訪問(wèn)者森渐。

應(yīng)用實(shí)例:您在朋友家做客,您是訪問(wèn)者冒晰,朋友接受您的訪問(wèn)同衣,您通過(guò)朋友的描述,然后對(duì)朋友的描述做出一個(gè)判斷壶运,這就是訪問(wèn)者模式乳怎。

優(yōu)點(diǎn): 1、符合單一職責(zé)原則。 2蚪缀、優(yōu)秀的擴(kuò)展性。 3恕出、靈活性询枚。

缺點(diǎn): 1、具體元素對(duì)訪問(wèn)者公布細(xì)節(jié)浙巫,違反了迪米特原則金蜀。 2、具體元素變更比較困難的畴。 3渊抄、違反了依賴倒置原則,依賴了具體類(lèi)丧裁,沒(méi)有依賴抽象护桦。

使用場(chǎng)景: 1、對(duì)象結(jié)構(gòu)中對(duì)象對(duì)應(yīng)的類(lèi)很少改變煎娇,但經(jīng)常需要在此對(duì)象結(jié)構(gòu)上定義新的操作二庵。 2、需要對(duì)一個(gè)對(duì)象結(jié)構(gòu)中的對(duì)象進(jìn)行很多不同的并且不相關(guān)的操作缓呛,而需要避免讓這些操作"污染"這些對(duì)象的類(lèi)催享,也不希望在增加新操作時(shí)修改這些類(lèi)。

注意事項(xiàng):訪問(wèn)者可以對(duì)功能進(jìn)行統(tǒng)一哟绊,可以做報(bào)表因妙、UI、攔截器與過(guò)濾器票髓。


QQ截圖20200520155253.png

MVC 模式

MVC 模式代表 Model-View-Controller(模型-視圖-控制器) 模式攀涵。這種模式用于應(yīng)用程序的分層開(kāi)發(fā)。

  • Model(模型) - 模型代表一個(gè)存取數(shù)據(jù)的對(duì)象或 JAVA POJO炬称。它也可以帶有邏輯汁果,在數(shù)據(jù)變化時(shí)更新控制器。
  • View(視圖) - 視圖代表模型包含的數(shù)據(jù)的可視化玲躯。
  • Controller(控制器) - 控制器作用于模型和視圖上据德。它控制數(shù)據(jù)流向模型對(duì)象,并在數(shù)據(jù)變化時(shí)更新視圖跷车。它使視圖與模型分離開(kāi)棘利。
    QQ截圖20200520155425.png

    QQ截圖20200520155450.png

業(yè)務(wù)代表模式

業(yè)務(wù)代表模式(Business Delegate Pattern)用于對(duì)表示層和業(yè)務(wù)層解耦。它基本上是用來(lái)減少通信或?qū)Ρ硎緦哟a中的業(yè)務(wù)層代碼的遠(yuǎn)程查詢功能朽缴。在業(yè)務(wù)層中我們有以下實(shí)體善玫。

  • 客戶端(Client) - 表示層代碼可以是 JSP、servlet 或 UI java 代碼密强。
  • 業(yè)務(wù)代表(Business Delegate) - 一個(gè)為客戶端實(shí)體提供的入口類(lèi)茅郎,它提供了對(duì)業(yè)務(wù)服務(wù)方法的訪問(wèn)蜗元。
  • 查詢服務(wù)(LookUp Service) - 查找服務(wù)對(duì)象負(fù)責(zé)獲取相關(guān)的業(yè)務(wù)實(shí)現(xiàn),并提供業(yè)務(wù)對(duì)象對(duì)業(yè)務(wù)代表對(duì)象的訪問(wèn)系冗。
  • 業(yè)務(wù)服務(wù)(Business Service) - 業(yè)務(wù)服務(wù)接口奕扣。實(shí)現(xiàn)了該業(yè)務(wù)服務(wù)的實(shí)體類(lèi),提供了實(shí)際的業(yè)務(wù)實(shí)現(xiàn)邏輯掌敬。


    QQ截圖20200520155547.png

組合實(shí)體模式

組合實(shí)體模式(Composite Entity Pattern)用在 EJB 持久化機(jī)制中惯豆。一個(gè)組合實(shí)體是一個(gè) EJB 實(shí)體 bean,代表了對(duì)象的圖解奔害。當(dāng)更新一個(gè)組合實(shí)體時(shí)楷兽,內(nèi)部依賴對(duì)象 beans 會(huì)自動(dòng)更新,因?yàn)樗鼈兪怯?EJB 實(shí)體 bean 管理的华临。以下是組合實(shí)體 bean 的參與者芯杀。

  • 組合實(shí)體(Composite Entity) - 它是主要的實(shí)體 bean。它可以是粗粒的银舱,或者可以包含一個(gè)粗粒度對(duì)象瘪匿,用于持續(xù)生命周期。
  • 粗粒度對(duì)象(Coarse-Grained Object) - 該對(duì)象包含依賴對(duì)象寻馏。它有自己的生命周期棋弥,也能管理依賴對(duì)象的生命周期。
  • 依賴對(duì)象(Dependent Object) - 依賴對(duì)象是一個(gè)持續(xù)生命周期依賴于粗粒度對(duì)象的對(duì)象诚欠。

    策略(Strategies) - 策略表示如何實(shí)現(xiàn)組合實(shí)體顽染。
    QQ截圖20200520155630.png

數(shù)據(jù)訪問(wèn)對(duì)象模式

數(shù)據(jù)訪問(wèn)對(duì)象模式(Data Access Object Pattern)或 DAO 模式用于把低級(jí)的數(shù)據(jù)訪問(wèn) API 或操作從高級(jí)的業(yè)務(wù)服務(wù)中分離出來(lái)。以下是數(shù)據(jù)訪問(wèn)對(duì)象模式的參與者轰绵。

  • 數(shù)據(jù)訪問(wèn)對(duì)象接口(Data Access Object Interface) - 該接口定義了在一個(gè)模型對(duì)象上要執(zhí)行的標(biāo)準(zhǔn)操作粉寞。
  • 數(shù)據(jù)訪問(wèn)對(duì)象實(shí)體類(lèi)(Data Access Object concrete class) - 該類(lèi)實(shí)現(xiàn)了上述的接口。該類(lèi)負(fù)責(zé)從數(shù)據(jù)源獲取數(shù)據(jù)左腔,數(shù)據(jù)源可以是數(shù)據(jù)庫(kù)唧垦,也可以是 xml,或者是其他的存儲(chǔ)機(jī)制液样。
  • 模型對(duì)象/數(shù)值對(duì)象(Model Object/Value Object) - 該對(duì)象是簡(jiǎn)單的 POJO振亮,包含了 get/set 方法來(lái)存儲(chǔ)通過(guò)使用 DAO 類(lèi)檢索到的數(shù)據(jù)。


    QQ截圖20200520155711.png

前端控制器模式

前端控制器模式(Front Controller Pattern)是用來(lái)提供一個(gè)集中的請(qǐng)求處理機(jī)制鞭莽,所有的請(qǐng)求都將由一個(gè)單一的處理程序處理坊秸。該處理程序可以做認(rèn)證/授權(quán)/記錄日志,或者跟蹤請(qǐng)求澎怒,然后把請(qǐng)求傳給相應(yīng)的處理程序褒搔。以下是這種設(shè)計(jì)模式的實(shí)體。

  • 前端控制器(Front Controller) - 處理應(yīng)用程序所有類(lèi)型請(qǐng)求的單個(gè)處理程序,應(yīng)用程序可以是基于 web 的應(yīng)用程序星瘾,也可以是基于桌面的應(yīng)用程序走孽。
  • 調(diào)度器(Dispatcher) - 前端控制器可能使用一個(gè)調(diào)度器對(duì)象來(lái)調(diào)度請(qǐng)求到相應(yīng)的具體處理程序。
  • 視圖(View) - 視圖是為請(qǐng)求而創(chuàng)建的對(duì)象琳状。


    QQ截圖20200520155758.png

攔截過(guò)濾器模式

攔截過(guò)濾器模式(Intercepting Filter Pattern)用于對(duì)應(yīng)用程序的請(qǐng)求或響應(yīng)做一些預(yù)處理/后處理融求。定義過(guò)濾器,并在把請(qǐng)求傳給實(shí)際目標(biāo)應(yīng)用程序之前應(yīng)用在請(qǐng)求上算撮。過(guò)濾器可以做認(rèn)證/授權(quán)/記錄日志,或者跟蹤請(qǐng)求县昂,然后把請(qǐng)求傳給相應(yīng)的處理程序肮柜。以下是這種設(shè)計(jì)模式的實(shí)體。

  • 過(guò)濾器(Filter) - 過(guò)濾器在請(qǐng)求處理程序執(zhí)行請(qǐng)求之前或之后倒彰,執(zhí)行某些任務(wù)审洞。
  • 過(guò)濾器鏈(Filter Chain) - 過(guò)濾器鏈帶有多個(gè)過(guò)濾器,并在 Target 上按照定義的順序執(zhí)行這些過(guò)濾器待讳。
  • Target - Target 對(duì)象是請(qǐng)求處理程序芒澜。
  • 過(guò)濾管理器(Filter Manager) - 過(guò)濾管理器管理過(guò)濾器和過(guò)濾器鏈。
  • 客戶端(Client) - Client 是向 Target 對(duì)象發(fā)送請(qǐng)求的對(duì)象创淡。


    QQ截圖20200520155855.png

服務(wù)定位器模式

服務(wù)定位器模式(Service Locator Pattern)用在我們想使用 JNDI 查詢定位各種服務(wù)的時(shí)候痴晦。考慮到為某個(gè)服務(wù)查找 JNDI 的代價(jià)很高琳彩,服務(wù)定位器模式充分利用了緩存技術(shù)誊酌。在首次請(qǐng)求某個(gè)服務(wù)時(shí),服務(wù)定位器在 JNDI 中查找服務(wù)露乏,并緩存該服務(wù)對(duì)象碧浊。當(dāng)再次請(qǐng)求相同的服務(wù)時(shí),服務(wù)定位器會(huì)在它的緩存中查找瘟仿,這樣可以在很大程度上提高應(yīng)用程序的性能箱锐。以下是這種設(shè)計(jì)模式的實(shí)體。

  • 服務(wù)(Service) - 實(shí)際處理請(qǐng)求的服務(wù)劳较。對(duì)這種服務(wù)的引用可以在 JNDI 服務(wù)器中查找到驹止。
  • Context / 初始的 Context - JNDI Context 帶有對(duì)要查找的服務(wù)的引用。
  • 服務(wù)定位器(Service Locator) - 服務(wù)定位器是通過(guò) JNDI 查找和緩存服務(wù)來(lái)獲取服務(wù)的單點(diǎn)接觸兴想。
  • 緩存(Cache) - 緩存存儲(chǔ)服務(wù)的引用幢哨,以便復(fù)用它們。
  • 客戶端(Client) - Client 是通過(guò) ServiceLocator 調(diào)用服務(wù)的對(duì)象嫂便。


    QQ截圖20200520155938.png

傳輸對(duì)象模式

傳輸對(duì)象模式(Transfer Object Pattern)用于從客戶端向服務(wù)器一次性傳遞帶有多個(gè)屬性的數(shù)據(jù)捞镰。傳輸對(duì)象也被稱為數(shù)值對(duì)象。傳輸對(duì)象是一個(gè)具有 getter/setter 方法的簡(jiǎn)單的 POJO 類(lèi),它是可序列化的岸售,所以它可以通過(guò)網(wǎng)絡(luò)傳輸践樱。它沒(méi)有任何的行為。服務(wù)器端的業(yè)務(wù)類(lèi)通常從數(shù)據(jù)庫(kù)讀取數(shù)據(jù)凸丸,然后填充 POJO拷邢,并把它發(fā)送到客戶端或按值傳遞它。對(duì)于客戶端屎慢,傳輸對(duì)象是只讀的瞭稼。客戶端可以創(chuàng)建自己的傳輸對(duì)象腻惠,并把它傳遞給服務(wù)器环肘,以便一次性更新數(shù)據(jù)庫(kù)中的數(shù)值。以下是這種設(shè)計(jì)模式的實(shí)體集灌。

  • 業(yè)務(wù)對(duì)象(Business Object) - 為傳輸對(duì)象填充數(shù)據(jù)的業(yè)務(wù)服務(wù)悔雹。
  • 傳輸對(duì)象(Transfer Object) - 簡(jiǎn)單的 POJO,只有設(shè)置/獲取屬性的方法欣喧。
  • 客戶端(Client) - 客戶端可以發(fā)送請(qǐng)求或者發(fā)送傳輸對(duì)象到業(yè)務(wù)對(duì)象腌零。


    QQ截圖20200520160017.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市唆阿,隨后出現(xiàn)的幾起案子益涧,更是在濱河造成了極大的恐慌,老刑警劉巖酷鸦,帶你破解...
    沈念sama閱讀 212,718評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件饰躲,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡臼隔,警方通過(guò)查閱死者的電腦和手機(jī)嘹裂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)摔握,“玉大人寄狼,你說(shuō)我怎么就攤上這事“碧剩” “怎么了泊愧?”我有些...
    開(kāi)封第一講書(shū)人閱讀 158,207評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)盛正。 經(jīng)常有香客問(wèn)我删咱,道長(zhǎng),這世上最難降的妖魔是什么豪筝? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,755評(píng)論 1 284
  • 正文 為了忘掉前任痰滋,我火速辦了婚禮摘能,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘敲街。我一直安慰自己团搞,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,862評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布多艇。 她就那樣靜靜地躺著逻恐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪峻黍。 梳的紋絲不亂的頭發(fā)上复隆,一...
    開(kāi)封第一講書(shū)人閱讀 50,050評(píng)論 1 291
  • 那天,我揣著相機(jī)與錄音姆涩,去河邊找鬼昏名。 笑死,一個(gè)胖子當(dāng)著我的面吹牛阵面,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播洪鸭,決...
    沈念sama閱讀 39,136評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼样刷,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了览爵?” 一聲冷哼從身側(cè)響起置鼻,我...
    開(kāi)封第一講書(shū)人閱讀 37,882評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蜓竹,沒(méi)想到半個(gè)月后箕母,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,330評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡俱济,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,651評(píng)論 2 327
  • 正文 我和宋清朗相戀三年嘶是,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蛛碌。...
    茶點(diǎn)故事閱讀 38,789評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡聂喇,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蔚携,到底是詐尸還是另有隱情希太,我是刑警寧澤,帶...
    沈念sama閱讀 34,477評(píng)論 4 333
  • 正文 年R本政府宣布酝蜒,位于F島的核電站誊辉,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏亡脑。R本人自食惡果不足惜堕澄,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,135評(píng)論 3 317
  • 文/蒙蒙 一邀跃、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧奈偏,春花似錦坞嘀、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,864評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至裁蚁,卻和暖如春矢渊,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背枉证。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,099評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工矮男, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人室谚。 一個(gè)月前我還...
    沈念sama閱讀 46,598評(píng)論 2 362
  • 正文 我出身青樓毡鉴,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親秒赤。 傳聞我的和親對(duì)象是個(gè)殘疾皇子猪瞬,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,697評(píng)論 2 351