設(shè)計(jì)模式深度解析34講學(xué)習(xí)總結(jié)

一务豺、設(shè)計(jì)原則

1.1.為什么要學(xué)習(xí)設(shè)計(jì)模式蹦狂?

趁早學(xué)習(xí)設(shè)計(jì)模式對(duì)以后進(jìn)階很有幫助誓篱,良好的設(shè)計(jì)模式掌握能力一是能幫助你順利通過面試朋贬,找到更好的工作,二是能幫你更好地進(jìn)階架構(gòu)師窜骄、技術(shù)布道者锦募,對(duì)那些喜歡鉆研技術(shù)的開發(fā)人員來說是很有益的。

1.2.七大設(shè)計(jì)原則

開閉原則

軟件實(shí)體應(yīng)當(dāng)對(duì)擴(kuò)展開放邻遏,對(duì)修改關(guān)閉

模塊應(yīng)該在盡量不修改代碼的前提下進(jìn)行拓展糠亩,這就需要使用接口和抽象類來實(shí)現(xiàn)預(yù)期效果。

開閉原則要求我們盡可能通過拓展來實(shí)現(xiàn)變化准验,盡可能少地改變已有模塊赎线,特別是底層模塊。

開閉原則總結(jié):

提高代碼復(fù)用性

提高代碼的可維護(hù)性

單一職責(zé)原則

保證設(shè)計(jì)類糊饱、接口垂寥、方法時(shí)做到功能單一,權(quán)責(zé)明確另锋。

單一職責(zé)原則滞项,指的是一個(gè)類或者模塊有且只有一個(gè)改變的原因。

核心就是解耦和增強(qiáng)內(nèi)聚性

單一職責(zé)可以降低類的復(fù)雜性夭坪,提高代碼可讀性文判、可維護(hù)性

里氏替換原則

所有引用基類的地方必須能透明地使用其子類的對(duì)象

里氏替換原則是開閉原則的實(shí)現(xiàn)基礎(chǔ),它告訴我們?cè)O(shè)計(jì)程序的時(shí)候盡可能使用基類進(jìn)行對(duì)象的定義及引用室梅,具體運(yùn)行時(shí)再?zèng)Q定基類對(duì)應(yīng)的具體子類型戏仓。

里氏替換原則總結(jié):

里氏替換可以提高代碼復(fù)用性,子類繼承父類時(shí)自然繼承到了父類的屬性和方法

提高代碼可拓展性亡鼠,子類通過實(shí)現(xiàn)父類方法進(jìn)行功能拓展柜去,個(gè)性化定制

里氏替換中的繼承有侵入性。繼承拆宛,就必然擁有父類的屬性和方法

增加了代碼的耦合性嗓奢。父類方法或?qū)傩缘淖兏枰紤]子類所引發(fā)的變更

依賴倒置原則

程序要依賴于抽象接口浑厚,不要依賴于具體實(shí)現(xiàn)股耽。簡(jiǎn)單的說就是要求對(duì)抽象進(jìn)行編程,不要對(duì)實(shí)現(xiàn)進(jìn)行編程

其核心思想是:要面向接口編程钳幅,不要面向?qū)崿F(xiàn)編程物蝙。

依賴倒置原則總結(jié):

高層模塊不應(yīng)該依賴低層模塊,都應(yīng)該依賴抽象(接口或抽象類)

接口或抽象類不應(yīng)該依賴于實(shí)現(xiàn)類

實(shí)現(xiàn)類應(yīng)該依賴于接口或抽象類

接口隔離原則

Interface Segregation Principle(ISP)敢艰,客戶端不應(yīng)該依賴它不需要的接口诬乞,類間的依賴關(guān)系應(yīng)該建立在最小的接口上。

接口隔離原則總結(jié):

接口盡量粒度化,保持接口純潔性

接口要高內(nèi)聚震嫉,即減少對(duì)外交互

迪米特法則

或者叫最少知識(shí)原則森瘪,一個(gè)軟件實(shí)體應(yīng)當(dāng)盡可能少地與其它實(shí)體發(fā)生相互作用。迪米特法則的初衷在于降低類之間的耦合票堵。

迪米特法則總結(jié):

類定義時(shí)盡量?jī)?nèi)斂扼睬,少使用 public 權(quán)限修飾符,盡量使用 private悴势、protected 等窗宇。

合成復(fù)用原則

通過將已有的對(duì)象納入新對(duì)象中,作為新對(duì)象的成員對(duì)象來實(shí)現(xiàn)的特纤,新對(duì)象可以調(diào)用已有對(duì)象的功能军俊,從而達(dá)到復(fù)用。

原則是盡量首先使用合成 / 聚合的方式捧存,而不是使用繼承粪躬。

合成和聚合都是關(guān)聯(lián)的特殊種類。合成是值的聚合(Aggregation by Value)矗蕊,而復(fù)合是引用的聚合(Aggregation by Reference)短蜕。

類之間有三種基本關(guān)系氢架,分別是:關(guān)聯(lián)(聚合和組合)傻咖、泛化(與繼承同一概念)、依賴岖研。

聚合卿操,用來表示整體與部分的關(guān)系或者 “擁有” 關(guān)系。代表部分的對(duì)象可能會(huì)被代表多個(gè)整體的對(duì)象所擁有孙援,但是并不一定會(huì)隨著整體對(duì)象的銷毀而銷毀害淤,部分的生命周期可能會(huì)超越整體。

合成拓售,用來表示一種強(qiáng)得多的 “擁有” 關(guān)系窥摄。部分和整體的生命周期是一致的,一個(gè)合成的新的對(duì)象完全擁有對(duì)其組成部分的支配權(quán)础淤,包括創(chuàng)建和泯滅崭放。

合成復(fù)用原則總結(jié):

新對(duì)象可以調(diào)用已有對(duì)象的功能,從而達(dá)到對(duì)象復(fù)用

二鸽凶、創(chuàng)建型模式

2.1.簡(jiǎn)單工廠模式——?jiǎng)e具匠心

該模式將對(duì)象的具體實(shí)例過程抽象化币砂,并不關(guān)心具體的創(chuàng)建過程。通常玻侥,工廠模式被用來定義一個(gè)對(duì)象模型决摧,之后,便可快速規(guī)模化實(shí)例化對(duì)象掌桩。

實(shí)質(zhì):一個(gè)工廠類根據(jù)傳入的參數(shù)边锁,動(dòng)態(tài)決定應(yīng)該創(chuàng)建哪一類產(chǎn)品類(這些產(chǎn)品類均繼承自一個(gè)父類或接口)實(shí)例。

優(yōu)點(diǎn):

一個(gè)調(diào)用者想創(chuàng)建某個(gè)對(duì)象拘鞋,只需知道其名稱即可

屏蔽具體行為實(shí)現(xiàn)砚蓬,調(diào)用者只需關(guān)心產(chǎn)品接口,減輕調(diào)用者負(fù)擔(dān)

拓展性高盆色,如果想增加一個(gè)產(chǎn)品類灰蛙,只需拓展一個(gè)工廠類即可

具體分類

普通簡(jiǎn)單工廠模式:建立一個(gè)具體工廠類,對(duì)實(shí)現(xiàn)了同一接口的一些類進(jìn)行實(shí)例的創(chuàng)建

多方法簡(jiǎn)單工廠

靜態(tài)方法簡(jiǎn)單工廠

簡(jiǎn)單工廠的延伸 — 工廠方法模式

創(chuàng)建一個(gè)接口和多個(gè)工廠類

總結(jié):

工廠方法模式中隔躲,核心的工廠類(這里為 Provider 接口)不再負(fù)責(zé)所有產(chǎn)品的創(chuàng)建摩梧,而是將具體創(chuàng)建的工作交給子類去做,該核心類僅扮演抽象工廠的角色宣旱,負(fù)責(zé)給出具體工廠子類必須實(shí)現(xiàn)的接口仅父,而不接觸哪一個(gè)產(chǎn)品類應(yīng)該被實(shí)例化的細(xì)節(jié),拓展性較簡(jiǎn)單工廠模式提升明顯浑吟。

2.2.抽象工廠模式——分而治之

定義:為創(chuàng)建一組相關(guān)或相互依賴的對(duì)象提供一個(gè)接口笙纤,而且無須指定它們的具體類

工廠方法模式針對(duì)的是同一類或同等級(jí)產(chǎn)品,而抽象工廠模式針對(duì)的是多種類(多等級(jí))的產(chǎn)品設(shè)計(jì)

產(chǎn)品族:一組相關(guān)或相互依賴的對(duì)象组力,比如省容,PC 機(jī)的主板和顯卡就是兩個(gè)相互依賴的產(chǎn)品線(也叫做產(chǎn)品族)

特點(diǎn):

系統(tǒng)中有多個(gè)產(chǎn)品族,每個(gè)具體工廠負(fù)責(zé)創(chuàng)建同一族但屬于不同產(chǎn)品等級(jí)(產(chǎn)品種類)的產(chǎn)品

系統(tǒng)一次只能消費(fèi)某一族產(chǎn)品燎字,即相同產(chǎn)品族的產(chǎn)品是一起被使用的

抽象工廠模式中的抽象工廠類的職責(zé)就是定義每個(gè)工廠要實(shí)現(xiàn)的功能腥椒,即定義多個(gè)產(chǎn)品族的產(chǎn)品的創(chuàng)建。這里候衍,同一產(chǎn)品族下有多個(gè)產(chǎn)品時(shí)笼蛛,對(duì)應(yīng)的抽象工廠就會(huì)有多個(gè)抽象方法用來提供創(chuàng)建這些產(chǎn)品的接口。

組成角色

抽象工廠(Abstract Factory):提供了創(chuàng)建產(chǎn)品的接口蛉鹿,包含多個(gè)創(chuàng)建產(chǎn)品的方法滨砍,即包含多個(gè)類似 new Product () 的方法;

具體工廠(Concrete Factory):實(shí)現(xiàn)抽象工廠定義的接口妖异,完成某個(gè)具體產(chǎn)品的創(chuàng)建惋戏;

抽象產(chǎn)品(Abstract Product):抽象產(chǎn)品定義,一般有多少抽象產(chǎn)品随闺,抽象工廠中就包含多少個(gè)創(chuàng)建產(chǎn)品的方法日川;

具體產(chǎn)品(Concrete Product):抽象產(chǎn)品的實(shí)現(xiàn)類。

2.3.單例模式——天下無雙

定義:私有化構(gòu)造函數(shù)的類可以提供相應(yīng)的 “接口”(一般就是靜態(tài)方法)來返回自己的唯一實(shí)例供外部調(diào)用矩乐,確保只生成一個(gè)實(shí)例龄句。

應(yīng)用場(chǎng)景:

想確保任何情況下都絕對(duì)只有一個(gè)實(shí)例

想在程序上表現(xiàn)出” 只存在一個(gè)實(shí)例 “

也就是:

只有一個(gè)實(shí)例

自我實(shí)例化

提供全局訪問點(diǎn)

提供全局訪問點(diǎn)回论,就是說除了公共訪問點(diǎn)之外,不能通過其他訪問點(diǎn)訪問該實(shí)例

一個(gè)類只能創(chuàng)建一個(gè)實(shí)例分歇,那么該類就稱為單例類傀蓉,包含如下實(shí)現(xiàn):

私有化的構(gòu)造函數(shù)

私有化的類成員變量

公共的類實(shí)例的訪問方法

懶漢式:類加載時(shí)沒有創(chuàng)建實(shí)例,而是在調(diào)用 方法時(shí)才去創(chuàng)建單例职抡,所以就會(huì)存在線程安全性問題葬燎。但是每次訪問都有同步問題,消耗資源缚甩,影響性能

餓漢式:直接在類創(chuàng)建的同時(shí)就生成靜態(tài)成員變量供外部使用谱净,即預(yù)先加載法,所以不存在線程安全性問題

優(yōu)缺點(diǎn):

單例模式一般拓展困難擅威,除了修改代碼幾乎沒有選擇壕探;

單例模式與單一職責(zé)原則沖突。一個(gè)類郊丛,通常只關(guān)心它要實(shí)現(xiàn)的業(yè)務(wù)邏輯李请,但是單例模式既要關(guān)心自己是否單例,又要實(shí)現(xiàn)業(yè)務(wù)邏輯厉熟,融合性比較高导盅。

應(yīng)用場(chǎng)景:

要求生成唯一序列號(hào)的環(huán)境;

網(wǎng)站計(jì)數(shù)器揍瑟,一般采用單例模式白翻,否則難以同步;

文件系統(tǒng)月培、打印機(jī)嘁字、資源管理器等恩急,因?yàn)榈讓淤Y源只能同時(shí)被一方操縱杉畜,所以這些模塊暴露的接口必然是單例的

Java 中的 dao、service 一般都是單例的衷恭,而 action 層一般都是多例此叠。

Spring實(shí)現(xiàn)單例模式:

在 Spring 中,Bean 可以被定義為兩種模式:prototype(多例)和 singleton(單例)

多例:對(duì)該 bean 每次請(qǐng)求時(shí)都會(huì)獲取一個(gè)新的 bean 實(shí)例随珠,類似于 new 操作灭袁。

bean 的作用域可以通過 bean 標(biāo)簽的 scope 屬性進(jìn)行設(shè)置,一般 scope 有如下幾種值:

singleton(單例):任何時(shí)候獲取到的 bean 都是同一個(gè)實(shí)例窗看;

prototype(多例):任何時(shí)候獲取到的 bean 都是新的實(shí)例茸歧;

request:在 WEB 應(yīng)用程序中,每一個(gè)實(shí)例的作用域都為 request 范圍显沈;

session:在 WEB 應(yīng)用程序中软瞎,每一個(gè)實(shí)例的作用域都為 session 范圍逢唤。

Spring 的單例模式又分為餓漢模式和懶漢模式,其中餓漢模式是缺省模式涤浇,懶漢模式則需要在 bean 的定義處使用 default-lazy-init=“true” 來聲明為懶漢模式

Spring 對(duì)單例的底層實(shí)現(xiàn)是通過單例注冊(cè)表的方式實(shí)現(xiàn)的鳖藕;Spring 為實(shí)現(xiàn)單例類可繼承,就使用了單例注冊(cè)表(登記敝欢А)形式著恩。

登記薄基本功能是:對(duì)于已經(jīng)登記過的單例,則從工廠直接返回蜻展,對(duì)于沒有登記的喉誊,則先登記,而后返回纵顾」郏基本點(diǎn)如下:

使用 Map 實(shí)現(xiàn)注冊(cè)表

使用 protect 取代原先的 private 的構(gòu)造方法,確保子類可繼承

2.4.建造者模式——步步為營(yíng)

定義:將一個(gè)復(fù)雜的對(duì)象的構(gòu)建與它的表示相分離片挂,使得同樣的構(gòu)建過程可以創(chuàng)建出不同的表示幻林。所以建造者模式(Builder Pattern)也叫做生成器模式

組成角色:

建造者(Builder):Builder 角色負(fù)責(zé)定義用來生成實(shí)例的接口(API);

具體的建造者(ConcreateBuilder):ConcreateBuilder 角色是負(fù)責(zé)實(shí)現(xiàn) Builder 角色定義的接口的實(shí)現(xiàn)類音念。針對(duì)不同的商業(yè)邏輯沪饺,具體化復(fù)雜對(duì)象的各部分的創(chuàng)建。在建造完成之后提供產(chǎn)品的實(shí)例闷愤;

監(jiān)工(Director):Director 角色負(fù)責(zé)使用 Builder 角色的接口 API 來生成實(shí)例整葡。內(nèi)部不涉及具體產(chǎn)品信息,只負(fù)責(zé)保證對(duì)象各部分完整創(chuàng)建或按照某種順序進(jìn)行創(chuàng)建讥脐。即 Director 是負(fù)責(zé)指揮如何 build 的遭居,只負(fù)責(zé)調(diào)度,具體實(shí)施交給具體的建造者旬渠;

產(chǎn)品(Product):即要?jiǎng)?chuàng)建的復(fù)雜對(duì)象俱萍;

使用者(Client):實(shí)際使用 Builder 模式的角色

優(yōu)缺點(diǎn):

封裝性:客戶端不必知道產(chǎn)品內(nèi)部組合細(xì)節(jié),只需關(guān)心我們要生成某個(gè)對(duì)象告丢,具體對(duì)象產(chǎn)生細(xì)節(jié)不必知曉枪蘑。Main 類并不知道 Builder 類,它只是調(diào)用了 Director 類的 construct 方法完成對(duì)象的獲柔狻岳颇;

建造者獨(dú)立,易于拓展:上面我們只列舉了 ConcreteBuilder 建造者類颅湘,如果需要其它建造者新建類即可话侧。建造者之間彼此獨(dú)立,系統(tǒng)拓展性好闯参,符合開閉原則瞻鹏;

便于控制細(xì)節(jié)風(fēng)險(xiǎn):由于具體建造者是獨(dú)立的术羔,因此可以對(duì)具體建造過程逐步細(xì)化,不會(huì)對(duì)其它模塊產(chǎn)生影響乙漓。

應(yīng)用場(chǎng)景:

產(chǎn)品類非常復(fù)雜级历,不同的調(diào)度產(chǎn)生不同的結(jié)果時(shí),使用建造者模式比較適合叭披;

相同的組件或配件都可以裝配到一個(gè)對(duì)象寥殖,但是產(chǎn)生的結(jié)果又不相同,可以使用建造者模式涩蜘。

建造者模式 VS 工廠方法模式

建造者模式關(guān)注的是零件類型和裝配順序(工藝)同為創(chuàng)建型模式嚼贡,注重點(diǎn)不同。另外工廠模式只有一個(gè)建造方法同诫,而建造者模式有多個(gè)建造零部件的方法并且強(qiáng)調(diào)建造順序粤策,而工廠模式?jīng)]有順序的概念。

2.5.原型模式 —— 依法炮制

定義:從設(shè)計(jì)模式的角度講误窖,原型模式是一種創(chuàng)建型模式叮盘,擺脫了類的構(gòu)造模式,原型模式告訴我們霹俺,想要?jiǎng)?chuàng)建一個(gè)對(duì)象柔吼,我們不必關(guān)心對(duì)象的具體類型,而是找到一個(gè)對(duì)象丙唧,然后通過克隆來創(chuàng)建一個(gè)一模一樣的對(duì)象愈魏。

實(shí)現(xiàn)關(guān)鍵:語言本身是否提供了 clone 方法

注意:所有的 java 類都繼承自 java.lang.Object 類,而 Object 類默認(rèn)提供了 clone 方法用來實(shí)現(xiàn)對(duì)象復(fù)制想际,能夠?qū)崿F(xiàn)的 java 類必須實(shí)現(xiàn)一個(gè)叫做 Cloneable 的接口培漏,用來標(biāo)識(shí)該類是可以被復(fù)制的,如果一個(gè)類沒有實(shí)現(xiàn) Cloneable 接口而調(diào)用 Object.clone 的話胡本,那么 java 會(huì)拋出 CloneNotSupportedException 異常牌柄。

淺拷貝VS深拷貝

淺拷貝:直接將原對(duì)象 birth 屬性的引用值賦給新的對(duì)象 p2 的 birth 屬性,這樣兩個(gè)對(duì)象的 birth 指向的是用一個(gè) Date 對(duì)象

深拷貝:將原對(duì)象 birth 指向的 Date 對(duì)象復(fù)制一份打瘪,創(chuàng)建一個(gè)相同的 Date 對(duì)象友鼻,然后將這個(gè)新的 Date 對(duì)象的引用賦給新拷貝的 p2 對(duì)象的 birth 屬性傻昙,這樣 p1 和 p2 的 birth 就分別指向了兩個(gè)不同的 Date 對(duì)象

序列化和反序列化

序列化是指將對(duì)象的狀態(tài)信息轉(zhuǎn)換為可以存儲(chǔ)或傳輸?shù)男问降倪^程闺骚。在序列化期間,對(duì)象將其當(dāng)前狀態(tài)寫入到臨時(shí)或持久性存儲(chǔ)區(qū)妆档。以后僻爽,可以通過從存儲(chǔ)區(qū)中讀取或反序列化對(duì)象的狀態(tài),重新創(chuàng)建該對(duì)象贾惦。

從字節(jié)流創(chuàng)建對(duì)象的相反的過程稱為反序列化胸梆。

應(yīng)用場(chǎng)景

原型模式一般很少單獨(dú)出現(xiàn)敦捧,一般都是和工廠方法模式一起搭配使用,通過 clone 來創(chuàng)建新的對(duì)象碰镜,然后由工廠方法返回兢卵。依賴倒置原則提醒我們創(chuàng)建對(duì)象的時(shí)候盡量不要依賴具體的對(duì)象類型,原型模式就很好的印證了這句話绪颖,避免僵硬地使用 new 來進(jìn)行對(duì)象創(chuàng)建秽荤。

優(yōu)點(diǎn):

向客戶隱藏新實(shí)例生成的細(xì)節(jié)

某些環(huán)境下,復(fù)制對(duì)象比新建對(duì)象更有效

提供讓客戶自主創(chuàng)建未知類型對(duì)象的方法

減少子類的構(gòu)造柠横,原型模式通過克隆而不是工廠方法來產(chǎn)生一個(gè)對(duì)象

缺點(diǎn):

對(duì)象復(fù)制有時(shí)比較復(fù)雜窃款,特別是對(duì)象層級(jí)嵌套很深時(shí)

三、結(jié)構(gòu)型模式

3.1.適配器模式——承上啟下

定義:將一個(gè)接口轉(zhuǎn)換成客戶希望的另一個(gè)接口牍氛,使接口不兼容的那些類可以一起工作晨继,解決的痛點(diǎn)便是因接口不兼容導(dǎo)致的類不能正常工作的問題。

使用時(shí)機(jī):

現(xiàn)有的類或接口不能滿足需求搬俊,且一般無法直接修改現(xiàn)有類或接口紊扬。比方該類為三方提供,就無法修改唉擂,亦或者像A珠月、B 這種已經(jīng)塑模成型的物件,可能已大規(guī)模在使用中楔敌,所以不允許修改啤挎。

想要建立一個(gè)可以重復(fù)使用的類,用于與一些彼此之間沒有太大關(guān)聯(lián)的一些類卵凑,包括一些可能在將來引進(jìn)的類一起工作庆聘,這些源類不一定有一致的接口。

適配器模式勺卢,根據(jù)適配器類與適配者類的關(guān)系不同伙判,適配器模式可分為對(duì)象適配器和類適配器兩種,在對(duì)象適配器模式中黑忱,適配器與適配者之間是關(guān)聯(lián)關(guān)系宴抚;在類適配器模式中,適配器與適配者之間是繼承(或?qū)崿F(xiàn))關(guān)系甫煞。

組成角色:

目標(biāo)角色(Target):該角色定義把其它類轉(zhuǎn)換為何種接口菇曲,也就是我們的期望接口,可以是一個(gè)抽象類或接口抚吠,也可以是具體類常潮。

適配器角色(Adapter):適配器可以調(diào)用另一個(gè)接口,作為一個(gè)轉(zhuǎn)換器楷力,對(duì) Adaptee 和 Target 進(jìn)行適配喊式,適配器類是適配器模式的核心孵户,通常都是一個(gè)具體的類。

源角色(被適配 Adaptee ):你想把誰轉(zhuǎn)換成目標(biāo)角色岔留,這個(gè)“誰”就是源角色夏哭,它是已經(jīng)存在的、運(yùn)行良好的類或?qū)ο笙琢?jīng)過適配器角色的包裝方庭,它會(huì)成為一個(gè)嶄新、靚麗的角色酱固。

請(qǐng)求者(Client):該角色負(fù)責(zé)使用 Target 定義的方法進(jìn)行具體處理沉删。

類適配器(使用繼承)

class Adapter extends Adaptee implements Target

對(duì)象適配器(使用委托)

class Adapter extends Target

優(yōu)缺點(diǎn):

主要優(yōu)點(diǎn):

將目標(biāo)類和適配者類解耦谒府,通過引入一個(gè)適配器類來重用現(xiàn)有的適配者類,無須修改原有結(jié)構(gòu);

增加了類的透明性和復(fù)用性柳譬,將具體的業(yè)務(wù)實(shí)現(xiàn)過程封裝在適配者類中棒厘,對(duì)于客戶端類而言是透明的蕊蝗,而且提高了適配者的復(fù)用性盯捌,同一個(gè)適配者類可以在多個(gè)不同的系統(tǒng)中復(fù)用;

可以將兩個(gè)互不相干的類關(guān)聯(lián)在一起署隘;

增強(qiáng)系統(tǒng)靈活性宠能。

主要缺點(diǎn):

類適配器對(duì)于 Java、C# 等不支持多重類繼承的語言磁餐,一次最多只能適配一個(gè)適配者類违崇,不能同時(shí)適配多個(gè)適配者。

應(yīng)用場(chǎng)景:

系統(tǒng)需要使用一些現(xiàn)有的類诊霹,而這些類的接口(如方法名)不符合系統(tǒng)的需要羞延,甚至沒有這些類的源代碼,這時(shí)創(chuàng)建一個(gè)適配器就能間接去改造這個(gè)類中的方法脾还;

想創(chuàng)建一個(gè)可以重復(fù)使用的類伴箩,用于與一些彼此之間沒有太大關(guān)聯(lián)的一些類,包括一些可能在將來引進(jìn)的類一起工作鄙漏。

3.2.橋接模式 —— 牽線搭橋

定義:

橋接模式 (Bridge Pattern):將抽象部分與它的實(shí)現(xiàn)部分分離嗤谚,使它們都可以獨(dú)立地變化。它是一種對(duì)象結(jié)構(gòu)型模式怔蚌,又稱為柄體 (Handle and Body) 模式或接口 (Interface) 模式巩步。

Bridge 就是將類的功能層次結(jié)構(gòu)與實(shí)現(xiàn)層次結(jié)構(gòu)連接起來。

類的功能層次結(jié)構(gòu) Vs 實(shí)現(xiàn)層次結(jié)構(gòu)

功能層次結(jié)構(gòu)

父類具備基本功能

子類在父類基礎(chǔ)上添加新的功能

實(shí)現(xiàn)層次結(jié)構(gòu)

父類聲明抽象方法定義相關(guān)接口(API)

子類通過具體方法來實(shí)現(xiàn)接口(API)

組成角色

抽象化(Abstraction):該角色位于屬于 “類的功能層次結(jié)構(gòu)” 的最上層媚创,用于定義抽象接口渗钉,一般是抽象類而不是抽象接口。其內(nèi)部往往包含一個(gè)實(shí)現(xiàn)類接口實(shí)例(Implementor)钞钙,使用委托方式進(jìn)行內(nèi)部調(diào)用鳄橘;

改善后的抽象化,或者叫補(bǔ)充抽象類(RefinedAbstraction):該角色用于補(bǔ)充 Abstraction 功能而存在芒炼,通常情況下不再是抽象類而是具體的實(shí)現(xiàn)類瘫怜,在內(nèi)部可以直接調(diào)用 Implementor 中的業(yè)務(wù)方法;

實(shí)現(xiàn)者(Implementor):該角色位于 “類的實(shí)現(xiàn)層次結(jié)構(gòu)” 的最上層本刽,定義了用于實(shí)現(xiàn) Abstraction 角色的接口(API)鲸湃,這里的接口并非要和 Abstraction 中定義的完全一致,Implementor 只對(duì)這些接口進(jìn)行聲明子寓,具體實(shí)現(xiàn)還是要交給子類暗挑。通過委托,在 Abstraction 中斜友,不僅可以調(diào)用自己方法炸裆,還可以調(diào)用到 Implementor 中定義的方法;

具體實(shí)現(xiàn)者(ConcreteImplementor):該角色用于實(shí)現(xiàn) Implementor 角色中定義的接口鲜屏,不同的實(shí)現(xiàn)類提供不同的業(yè)務(wù)處理方法烹看,程序運(yùn)行時(shí),ConcreteImplementor 將替換 Abstraction 中的 Implementor洛史,提供給抽象類具體的業(yè)務(wù)操作方法惯殊。

優(yōu)缺點(diǎn)

抽象與實(shí)現(xiàn)相分離:抽象與實(shí)現(xiàn)相分離,從而讓抽象與實(shí)現(xiàn)分別獨(dú)立開來也殖,分別定義接口土思,有助于系統(tǒng)分層及產(chǎn)生更好的結(jié)構(gòu)化系統(tǒng);

更好的拓展性:系統(tǒng)拓展時(shí)忆嗜,因?yàn)槌橄笈c實(shí)現(xiàn)已經(jīng)分別獨(dú)立浪漠,所以可以進(jìn)行分別拓展不會(huì)相互影響,從而大大提高系統(tǒng)拓展性霎褐。

3.3.過濾器模式——挑三揀四

定義

過濾器模式(Filter Pattern)又稱為標(biāo)準(zhǔn)模式(Criteria Pattern)是一種設(shè)計(jì)模式址愿,這種模式允許開發(fā)人員使用不同的標(biāo)準(zhǔn)來過濾一組對(duì)象,通過運(yùn)算邏輯以解耦的方式將它們聯(lián)系起來冻璃。這種類型的設(shè)計(jì)模式屬于結(jié)構(gòu)型模式响谓,說白了,就是按條件篩選一組對(duì)象出來省艳。

目的:使用不同標(biāo)準(zhǔn)來過濾一組對(duì)象

實(shí)現(xiàn):制定不同的規(guī)則來實(shí)現(xiàn)過濾娘纷,然后對(duì)過濾結(jié)果進(jìn)行分組

組成角色

抽象過濾器角色(AbstractFilter):負(fù)責(zé)定義過濾器的實(shí)現(xiàn)接口,具體的實(shí)現(xiàn)還要具體過濾器角色去參與跋炕,客戶端可以調(diào)用抽象過濾器角色中定義好的方法赖晶,將客戶端的所有請(qǐng)求委派到具體的實(shí)現(xiàn)類去,從而讓實(shí)現(xiàn)類去處理;

ConcreteFilter(具體過濾器角色):該角色負(fù)責(zé)具體篩選規(guī)則的邏輯實(shí)現(xiàn)遏插,最后再返回一個(gè)過濾后的數(shù)據(jù)集合捂贿,標(biāo)準(zhǔn)的過濾器只對(duì)數(shù)據(jù)做過濾,當(dāng)然也可以對(duì)集合中的數(shù)據(jù)做某項(xiàng)處理胳嘲,再將處理后的集合返回厂僧;

Subject(被過濾的主體角色):一個(gè)軟件系統(tǒng)中可以有一個(gè)或多個(gè)目標(biāo)角色,在具體過濾器角色中會(huì)對(duì)指定感興趣的目標(biāo)進(jìn)行處理了牛,以確保后面的數(shù)據(jù)確實(shí)是我想要的颜屠。

過濾器延伸——管道和過濾器

管道將一個(gè)個(gè)過濾器連接起來,形成一個(gè)過濾器鏈(過濾器鏈可以攜帶多個(gè)過濾器鹰祸,并且可以自定義順序執(zhí)行它們)

可以存在一個(gè)過濾器管理器的角色甫窟,負(fù)責(zé)管理過濾器和過濾器鏈

特點(diǎn)

可插拔:過濾器的設(shè)計(jì)概念要求其是支持可插拔設(shè)計(jì)的;

有序性:過濾器是被設(shè)計(jì)為一組組的過濾裝置蛙婴,要實(shí)現(xiàn)數(shù)據(jù)過濾粗井,就必須有順序性要求,比如我們要設(shè)計(jì)編解碼過濾器敬锐,用戶請(qǐng)求過來的 xml 數(shù)據(jù)會(huì)優(yōu)先通過 xml2json 過濾器進(jìn)行數(shù)據(jù)處理背传,完了再在響應(yīng)發(fā)出前進(jìn)行相應(yīng)的 json2xml 過濾處理,以保證客戶端交互以 xml 數(shù)據(jù)格式為準(zhǔn)的同時(shí)系統(tǒng)內(nèi)部數(shù)據(jù)交互還是維持 json 格式不變台夺;

過濾器的獨(dú)立性:每種過濾器必須是獨(dú)立的實(shí)體径玖,其狀態(tài)不受其它過濾器的影響,每個(gè)過濾器都有自己獨(dú)立的數(shù)據(jù)輸入輸出接口颤介,只要各個(gè)過濾器之間傳送的數(shù)據(jù)遵守共同的規(guī)約就可以相連接

3.4.組合模式——高度一致

定義

組合關(guān)系:部分與整體的關(guān)系梳星,有了整體才有部分,部分不能脫離整體而存在

聚合關(guān)系:整體和部分的關(guān)系滚朵,部分可以單獨(dú)存在

一致:整體和部分一致

3.4.裝飾器模式——添磚加瓦

定義:在不改變?cè)泄δ艿幕A(chǔ)上添加額外的裝飾功能

組成角色

抽象構(gòu)件(Component ):Component 是一個(gè)接口或者抽象類冤灾,也是最原始的對(duì)象,屬于模式核心角色辕近。用于定義一些抽象的接口或功能韵吨,以便后面的 ConcreteComponent 和 ConcreteDecorator 角色去實(shí)現(xiàn);

具體構(gòu)件(ConcreteComponent):ConcreteComponent 是最原始移宅、最基本的接口或抽象類 Component 的實(shí)現(xiàn)归粉,在模式中充當(dāng)被裝飾的角色,也就說我們模式要裝飾的對(duì)象就是 ConcreteComponent漏峰;

抽象裝飾角色(Decorator):Decorator 一般是一個(gè)抽象類糠悼,實(shí)現(xiàn)接口或者抽象方法,其內(nèi)部不一定有抽象方法定義浅乔,有可能只是單純繼承下 Component 抽象構(gòu)件倔喂;但是其內(nèi)部一般都有一個(gè) Component 角色的引用,表示 Decorator 需要裝飾的對(duì)象,一般該對(duì)象是 private 或者 protected 聲明席噩;

具體裝飾器角色(ConcreteDecorator):具體的裝飾器類班缰,繼承 Decorator 抽象裝飾器角色,實(shí)現(xiàn)了 Component 抽象角色中定義的接口(API)

3.5.外觀模式——分離解耦

定義

為各個(gè)子系統(tǒng)的一組接口提供一致的調(diào)用窗口或門面班挖,使得子系統(tǒng)更容易使用鲁捏,使得復(fù)雜的子系統(tǒng)與客戶端分離解耦

組成角色

門面角色(Facade):門面模式自然少不了門面角色芯砸,這就是我們的 Facade 類萧芙,一般情況下,該角色會(huì)將客戶端的請(qǐng)求委派給相應(yīng)的子系統(tǒng)去調(diào)用假丧,也就說該角色實(shí)際沒有啥實(shí)質(zhì)性的業(yè)務(wù)邏輯双揪,只是一個(gè)單純的委派類,用來實(shí)現(xiàn)客戶端和子系統(tǒng)的解耦包帚;

子系統(tǒng)角色(SubSystem):子系統(tǒng)并不是一個(gè)單一的類渔期,而是眾多類的一個(gè)系統(tǒng)集合。一般而言渴邦,子系統(tǒng)并不知道門面角色的存在疯趟,也就說對(duì)子系統(tǒng)而言,門面角色是完全透明的谋梭。子系統(tǒng)各自實(shí)現(xiàn)自己的功能信峻,包括類之間的相互調(diào)用等,這些都不受門面角色的影響瓮床。

優(yōu)缺點(diǎn)

外觀模式優(yōu)點(diǎn):

實(shí)現(xiàn)了子系統(tǒng)與客戶端之間關(guān)系的解耦盹舞;

客戶端屏蔽了子系統(tǒng)組件,使得客戶端所需處理的對(duì)象數(shù)目有所減少隘庄,使得子系統(tǒng)使用起來更加容易

外觀模式缺點(diǎn):

增加新的子系統(tǒng)可能需要修改外觀類或者客戶端的源代碼踢步,違背了開閉原則;

外觀類并沒有阻斷子系統(tǒng)被外部使用的可能性

3.6.享元模式——共享重用

定義:

使用共享對(duì)象有效地支持大量的細(xì)粒度的對(duì)象

組成角色

抽象享元角色(Flyweight):一般是一個(gè)具體的抽象類丑掺,同時(shí)定義了對(duì)象的外部狀態(tài)和內(nèi)部狀態(tài)的接口或?qū)崿F(xiàn)获印;

具體享元角色(ConcreteFlyweight):具體的一個(gè)產(chǎn)品類,實(shí)現(xiàn)了抽象享元角色中定義的接口街州,該角色需要注意的是內(nèi)部狀態(tài)的處理應(yīng)該與環(huán)境無關(guān)兼丰;

享元工廠(FlyweightFactory):該角色指責(zé)一般比較清晰,就是一個(gè)池工廠菇肃,提供池對(duì)象和獲取池中對(duì)象的方法

優(yōu)缺點(diǎn):

優(yōu)點(diǎn)

有效減少內(nèi)存數(shù)量地粪,使得相似或相同的對(duì)象在內(nèi)存中只保留一份,有效解決內(nèi)存溢出的問題

享元馬氏的外部狀態(tài)相對(duì)獨(dú)立琐谤,而不影響其內(nèi)部狀態(tài)蟆技,從而使得享元對(duì)象可以在不同的環(huán)境中被共享

缺點(diǎn)

內(nèi)部狀態(tài)與外部狀態(tài)的分離會(huì)變得比較復(fù)雜,使得程序更加復(fù)雜化

享元工廠中的對(duì)象進(jìn)行獲取的時(shí)候可能會(huì)存在線程安全問題

3.7.代理模式——托孤寄命

定義

代理模式給某對(duì)象提供一個(gè)代理對(duì)象,由代理對(duì)象來控制對(duì)原對(duì)象的引用

靜態(tài)代理組成角色

抽象主題角色(Subject):抽象主題角色往往是一個(gè)抽象類或接口质礼,用來定義被委托類也就是真實(shí)的業(yè)務(wù)處理類和代理類的一些通用操作旺聚;

具體的主題角色(RealSubject):該類實(shí)現(xiàn) Subject,是真實(shí)被委托的類眶蕉,也是具體業(yè)務(wù)邏輯的真正執(zhí)行者砰粹;

代理類或委托類(Proxy):該類同樣實(shí)現(xiàn) Subject,在客戶類和本地之間充當(dāng)中介作用造挽,將客戶端的業(yè)務(wù)操作委托給 RealSubject 執(zhí)行碱璃,并在執(zhí)行前后做一些預(yù)處理或者善后工作

動(dòng)態(tài)代理

jdk動(dòng)態(tài)代理

通過反射技術(shù)來創(chuàng)建類的加載器并且創(chuàng)建類的實(shí)例,根據(jù)類執(zhí)行方法并在方法執(zhí)行前后進(jìn)行前置或者后置通知等處理饭入。使用到的就是 Proxy 類的靜態(tài)方法 newProxyInstance嵌器,該方法會(huì)返回一個(gè)代理類對(duì)象

cglib動(dòng)態(tài)代理

優(yōu)缺點(diǎn)

優(yōu)點(diǎn):

智能化:通過動(dòng)態(tài)代理可以實(shí)現(xiàn)將頁面表單元素映射到Java對(duì)象

中介隔離:使用代理類隔離客戶類和目標(biāo)類;降低系統(tǒng)耦合度谐丢,擴(kuò)展性好爽航;可以起到對(duì)目標(biāo)對(duì)象的保護(hù)及增強(qiáng)功能

缺點(diǎn):

多出代理類,導(dǎo)致類設(shè)計(jì)時(shí)類數(shù)量增多乾忱,請(qǐng)求變緩

四讥珍、行為型模式

4.1.責(zé)任鏈模式——以訛傳訛

定義:

使多個(gè)對(duì)象都有機(jī)會(huì)處理請(qǐng)求,從而避免了請(qǐng)求的發(fā)送者和接受者之間的耦合關(guān)系窄瘟。將這些對(duì)象連成一條鏈衷佃,并沿著這條鏈傳遞該請(qǐng)求,直到有對(duì)象處理它為止

組成角色:

請(qǐng)求者(Client):Client 角色就是向鏈發(fā)送請(qǐng)求的角色寞肖,在上面的例子中纲酗,Main 函數(shù)扮演這個(gè)角色;

責(zé)任人的抽象類角色(Handler):Handler 角色是模式的核心新蟆,Handler 知道下一個(gè)責(zé)任人是誰觅赊,并根據(jù)責(zé)任人的處理能力選擇是否將請(qǐng)求轉(zhuǎn)發(fā)至下一個(gè)責(zé)任人。上面例子中琼稻,由 Handler 類扮演該角色吮螺;

具體責(zé)任人對(duì)象(ConcreteHandler):該角色是具體處理請(qǐng)求的對(duì)象,上面例子中帕翻,由 Primary鸠补、Middle、Senior 類扮演

優(yōu)缺點(diǎn)

優(yōu)點(diǎn):

責(zé)任鏈模式將請(qǐng)求和處理分開嘀掸,請(qǐng)求者不知道時(shí)誰處理的紫岩,處理者可以不用知道請(qǐng)求的全貌

提高系統(tǒng)的靈活性

缺點(diǎn):

降低系統(tǒng)性能:特別是鏈較長(zhǎng)時(shí),請(qǐng)求要從鏈頭遍歷到鏈尾

不利于調(diào)試:鏈?zhǔn)秸{(diào)用類似于遞歸方式睬塌,加劇調(diào)試難度

4.2.命令模式——上令下達(dá)

命令模式(Command Pattern)又稱行動(dòng)(Action)模式或交易(transaction)模式

英文定義:Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.

中文定義:將發(fā)送者泉蝌、接收者和調(diào)用命令封裝成對(duì)象歇万,客戶端調(diào)用的時(shí)候可以選擇不同的對(duì)象,從而實(shí)現(xiàn)發(fā)送者和接收者的完全解耦

組成角色

命令接口(Command)角色:該角色聲明一個(gè)接口勋陪,定義需要執(zhí)行的命令贪磺;

具體命令實(shí)現(xiàn)類(Concrete Command)角色:該角色定義一個(gè)接收者和行為之間的弱耦合,實(shí)現(xiàn)命令方法诅愚,并調(diào)用接收者的相應(yīng)操作寒锚;

調(diào)用者(Invoker)角色:該角色負(fù)責(zé)調(diào)用命令對(duì)象執(zhí)行請(qǐng)求;

接收者(Receiver)角色:該角色負(fù)責(zé)具體實(shí)施和執(zhí)行請(qǐng)求動(dòng)作(方法)违孝;

客戶端(Client)角色:串連執(zhí)行整個(gè)流程

優(yōu)缺點(diǎn)

優(yōu)點(diǎn):

類間解耦:調(diào)用者角色與接收者角色之間沒有任何依賴關(guān)系刹前,調(diào)用者實(shí)現(xiàn)功能時(shí)只需要調(diào)用 Command 中的 execute() 方法即可,不需要了解是哪個(gè)接收者執(zhí)行等浊;

可擴(kuò)展性:Command 的子類可以非常容易地?cái)U(kuò)展腮郊,而調(diào)用者 Invoker 和高層次的模塊 Client 不產(chǎn)生嚴(yán)重的代碼耦合

缺點(diǎn):

使用命令模式會(huì)導(dǎo)致系統(tǒng)有過多的具體命令類摹蘑,因?yàn)獒槍?duì)每一個(gè)命令都需要設(shè)計(jì)一個(gè)具體命令類

應(yīng)用場(chǎng)景

系統(tǒng)需要支持命令的撤銷(undo)筹燕,命令對(duì)象可以把狀態(tài)存儲(chǔ)起來,等到客戶端需要撤銷時(shí)衅鹿,可以調(diào)用 undo() 方法撒踪,將命令所產(chǎn)生的效果撤銷;

系統(tǒng)需要支持命令的撤銷(Undo)操作和恢復(fù)(Redo)操作大渤;

系統(tǒng)需要將一組操作組合在一起制妄,使用命令模式來實(shí)現(xiàn),可以很方便的增加新的命令

4.3.解釋器模式——解疑答惑

解釋器模式(Interpreter Pattern)提供了評(píng)估語言的語法或者表達(dá)式的方式泵三,屬于一種行為型的設(shè)計(jì)模式

英文定義:Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language.

中文定義:給定一門語言耕捞,定義它的文法的一種表示,并定義一個(gè)解釋器烫幕,該解釋器使用該表示來解釋語言中的句子

終結(jié)符號(hào)和非終結(jié)符號(hào)

終結(jié)符號(hào):運(yùn)算參數(shù)一般就是英文字母俺抽,執(zhí)行時(shí)各個(gè)參數(shù)需要賦上具體的數(shù)字值去替代英文字母執(zhí)行,運(yùn)算參數(shù)有一個(gè)共同點(diǎn)就是不管是 a较曼、b 或者其它參數(shù)磷斧,除了被賦值之外不需要做其它任何處理,是執(zhí)行時(shí)的最小單元

非終結(jié)符號(hào):運(yùn)算符號(hào)是進(jìn)行運(yùn)算時(shí)具體要被解釋器解釋執(zhí)行的部分捷犹,想象一下弛饭,假如我們計(jì)算機(jī)不知道如何處理類似 +、- 這種符號(hào)萍歉,我們是不要針對(duì)每一個(gè)符號(hào)寫一個(gè)解釋方法侣颂,以便告訴計(jì)算機(jī)該符號(hào)需要進(jìn)行何種操作,這也就是解釋器模式的核心——需要完成邏輯的解釋執(zhí)行操作枪孩,而運(yùn)算符號(hào)就是非終結(jié)符號(hào)

組成角色

抽象解釋器(AbstractExpression):抽象解釋器是一個(gè)上層抽象類憔晒,用來抽取定義公共的解釋方法:interpreter胳蛮,具體的解釋任務(wù)交給子類去完成;

終結(jié)符表達(dá)式(TerminalExpression):是抽象解釋器的子類丛晌,實(shí)現(xiàn)了與文法中的元素相關(guān)的解釋操作仅炊。一般模式中只會(huì)有一個(gè)終結(jié)符表達(dá)式也就是終結(jié)符的類,但是會(huì)有多個(gè)實(shí)例澎蛛,比如:a抚垄、b、c谋逻,這些終結(jié)符號(hào)可以任意多種但是只有一個(gè)類來描述呆馁;

非終結(jié)符表達(dá)式(NonTerminalExpression):也是抽象解釋器的子類,用來實(shí)現(xiàn)文法中與終結(jié)符相關(guān)的操作毁兆。該角色一般會(huì)有多個(gè)實(shí)現(xiàn)類浙滤,比如 +、- 運(yùn)算符號(hào)就各自對(duì)應(yīng)一種類實(shí)現(xiàn)气堕,分別對(duì)應(yīng)加法解釋類和減法解釋類纺腊,非終結(jié)符表達(dá)式的類的個(gè)數(shù)一般會(huì)有很多,因?yàn)槲覀兛蓤?zhí)行的操作一般會(huì)有很多茎芭,這也從側(cè)面加劇了該模式下類設(shè)計(jì)的復(fù)雜性揖膜;

上下文(Context):上下文一般用來定義各個(gè)解釋器需要的數(shù)據(jù)或公共功能,比如上面的表達(dá)式梅桩,我們使用上下文來保存各個(gè)參數(shù)的值壹粟,一般是一個(gè) HashMap 對(duì)象,以便后面所有解釋器都可以使用該上下文來獲取參數(shù)值

優(yōu)缺點(diǎn)

優(yōu)點(diǎn):

拓展性強(qiáng):修改文法規(guī)則只需要修改相應(yīng)的非終結(jié)符表達(dá)式就可以了宿百,即增加非終結(jié)符類就可以了

缺點(diǎn):

采用遞歸調(diào)用方法趁仙,不利于調(diào)試,增加了系統(tǒng)的復(fù)雜性以及降低了系統(tǒng)執(zhí)行的效率垦页;

解釋器模式比較容易造成類設(shè)計(jì)的膨脹雀费,主要是非終結(jié)符表達(dá)式類會(huì)隨著系統(tǒng)的復(fù)雜性而膨脹;

可利用的場(chǎng)景比較少外臂;

對(duì)于比較復(fù)雜的文法不好解析

應(yīng)用場(chǎng)景

一個(gè)簡(jiǎn)單語法需要解釋的場(chǎng)景坐儿,如:sql語法分析,用來解析那種比較標(biāo)準(zhǔn)的字符集宋光;

重復(fù)發(fā)生的問題可以使用解釋器模式貌矿,如:日志分析,日志分析時(shí)基礎(chǔ)數(shù)據(jù)是相同的類似于我們的終結(jié)符罪佳,但是日志格式往往是各異的逛漫,類似于非終結(jié)符,只需要指定具體的實(shí)現(xiàn)類即可

4.4.迭代器模式——循環(huán)迭代

迭代器模式(Iterator Pattern)又稱為游標(biāo)(Cursor)模式

英文定義:Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.

中文定義:提供一種方法訪問一個(gè)容器對(duì)象中各個(gè)元素赘艳,而又不需暴露該對(duì)象的內(nèi)部細(xì)節(jié)

注意:迭代器是為容器服務(wù)的酌毡,容器是指用來容納其他對(duì)象的對(duì)象克握,例如,Collection 集合類型枷踏、Set 類等

組成角色:

抽象迭代器(Iterator)角色:該角色負(fù)責(zé)定義訪問和遍歷元素的接口菩暗;

具體迭代器(Concrete Iterator)角色:該角色實(shí)現(xiàn) Iterator 接口,完成容器元素的遍歷旭蠕;

抽象聚集(Aggregate)角色:該角色提供創(chuàng)建迭代器角色的接口停团;

具體聚集(Concrete Aggregate)角色:該角色實(shí)現(xiàn)抽象聚集接口,創(chuàng)建出容納迭代器的對(duì)象

優(yōu)缺點(diǎn)

優(yōu)點(diǎn):

迭代器模式將數(shù)據(jù)存儲(chǔ)和數(shù)據(jù)遍歷的職責(zé)進(jìn)行分離掏熬;

迭代器模式簡(jiǎn)化了遍歷容器元素的操作佑稠;

迭代器模式使不同的容器,具備一個(gè)統(tǒng)一的遍歷接口旗芬;

迭代器模式封裝了遍歷算法舌胶,使算法獨(dú)立于聚集角色,調(diào)用者無須知道聚集對(duì)象的類型疮丛,即使聚集對(duì)象的類型發(fā)生變化幔嫂,也不會(huì)影響遍歷過程

缺點(diǎn):

由于迭代器模式將數(shù)據(jù)存儲(chǔ)和數(shù)據(jù)遍歷的職責(zé)進(jìn)行分離,如果增加新的聚合類这刷,同時(shí)需要增加與之相對(duì)應(yīng)的迭代器類婉烟,這使得類的個(gè)數(shù)會(huì)成對(duì)增加,在某種程度上來說增加了系統(tǒng)的復(fù)雜性

4.5.中介者模式——牽線搭橋

定義:定義一個(gè)中介對(duì)象來封裝對(duì)象之間的交互暇屋,使原有對(duì)象之間耦合松散,并且可以獨(dú)立地改變它們之間的交互

組成角色:

中介者(又稱仲裁者洞辣,Mediator):負(fù)責(zé)定義與 Colleague 角色進(jìn)行通信和做出角色的接口咐刨;

具體中介者、仲裁者(ConcreteMediator):負(fù)責(zé)實(shí)現(xiàn) Mediator 角色定義的接口扬霜,負(fù)責(zé)具體的業(yè)務(wù)執(zhí)行定鸟;

同事角色(Colleague):負(fù)責(zé)定義與 Mediator 角色進(jìn)行通信的接口;

具體同事角色(ConcreteColleague):實(shí)現(xiàn) Colleague 角色定義的接口著瓶,一般會(huì)有多個(gè)實(shí)現(xiàn)類

優(yōu)缺點(diǎn)

優(yōu)點(diǎn)

弱化對(duì)象間的依賴關(guān)系联予,即松耦合,降低同時(shí)類的耦合度材原,符合迪米特法則

將對(duì)象間的調(diào)用關(guān)系進(jìn)行封裝沸久,使得對(duì)象更容易復(fù)用

缺點(diǎn)

如果對(duì)象增多,就要去修改抽象中介者和具體的中介者角色

中介者角色承擔(dān)了太多了業(yè)務(wù)邏輯功能余蟹,流程復(fù)雜時(shí)就會(huì)顯得比較臃腫卷胯,不好管理

4.6.觀察者模式——發(fā)布訂閱

觀察者模式(Observer Pattern)也稱發(fā)布訂閱模式

英文定義:Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

中文定義:定義對(duì)象間一種一對(duì)多的依賴關(guān)系,使得每當(dāng)一個(gè)對(duì)象改變狀態(tài)威酒,則所有依賴于它的對(duì)象都會(huì)得到通知并被自動(dòng)更新

組成角色:

抽象主題(Subject)角色:該角色又稱為 “發(fā)布者” 或” 被觀察者 “窑睁,可以增加和刪除觀察者對(duì)象挺峡;

具體主題(Concrete Subject)角色:該角色又稱為 “具體發(fā)布者” 或 “具體被觀察者”,它將有關(guān)狀態(tài)存入具體觀察者對(duì)象担钮,在具體主題的內(nèi)部狀態(tài)改變時(shí)橱赠,給所有登記過(關(guān)聯(lián)了觀察關(guān)系)的觀察者發(fā)出通知;

抽象觀察者(Observer)角色:該角色又稱為 “訂閱者”箫津,定義一個(gè)接收通知的接口病线,在得到主題的通知時(shí)更新自己;

具體觀察者(Concrete Observer)角色:該角色又稱為 “具體訂閱者”鲤嫡,它會(huì)實(shí)現(xiàn)一個(gè)接收通知的方法送挑,用來使自身的狀態(tài)與主題的狀態(tài)相協(xié)調(diào)

優(yōu)缺點(diǎn)

優(yōu)點(diǎn):

觀察者和被觀察者之間,實(shí)現(xiàn)了抽象耦合暖眼。被觀察者角色所知道的只是一個(gè)具體觀察者集合惕耕,每一個(gè)具體觀察者都符合一個(gè)抽象觀察者的接口。被觀察者并不認(rèn)識(shí)任何一個(gè)具體的觀察者诫肠,它只知道它們都有一個(gè)共同的接口司澎。由于被觀察者和觀察者沒有緊密的耦合在一起,因此它們可以屬于不同的抽象化層次栋豫,且都非常容易擴(kuò)展挤安;

此模式為廣播模式,所有的觀察者只需要訂閱相應(yīng)的主題丧鸯,就能收到此主題下的所有廣播

缺點(diǎn):

觀察者只知道被觀察者會(huì)發(fā)生變化蛤铜,但不知道何時(shí)會(huì)發(fā)生變化;

如果主題之間有循環(huán)依賴丛肢,會(huì)導(dǎo)致系統(tǒng)崩潰围肥,所以在使用時(shí)要特別注意此種情況;

如果有很多個(gè)觀察者蜂怎,則每個(gè)通知會(huì)比較耗時(shí)

應(yīng)用場(chǎng)景

關(guān)聯(lián)行為的場(chǎng)景穆刻,例如,在一個(gè)系統(tǒng)中杠步,如果用戶完善了個(gè)人資料氢伟,就會(huì)增加積分、添加日志幽歼、開放一些功能權(quán)限等朵锣,就比較適合用觀察者模式;

消息隊(duì)列试躏,例如猪勇,需要隔離發(fā)布者和訂閱者,需要處理一對(duì)多關(guān)系的時(shí)候

4.7.狀態(tài)模式——虛懷若谷

英文定義:Allow an object to alter its behavior when its internal state changes.The object will appear to change its class.

中文定義:允許一個(gè)對(duì)象在其內(nèi)部狀態(tài)改變時(shí)改變其行為颠蕴,這個(gè)對(duì)象看起來好像是改變了其類泣刹。狀態(tài)模式是一種對(duì)象行為型模式

組成角色

上下文角色(Context):上下文角色一般是一個(gè)類助析,上下文角色會(huì)聚合很多和 state,這些 state 使用靜態(tài)常量修飾椅您,并且負(fù)責(zé) state 的狀態(tài)切換外冀;另外上下文角色還會(huì)包含抽象狀態(tài)角色中定義的所有行為如 request,然后內(nèi)部將請(qǐng)求委托給 state 的 handle 處理掀泳;

抽象狀態(tài)角色(State):抽象狀態(tài)角色一般是一個(gè)抽象類雪隧,用來定義具體狀態(tài)的公共行為比如 handle,任何具體狀態(tài)都必須實(shí)現(xiàn)該抽象類中的抽象方法员舵;

具體狀態(tài)角色(ConcreteState):繼承抽象狀態(tài)角色脑沿,實(shí)現(xiàn)抽象方法,實(shí)際處理來自 Context 的委托請(qǐng)求马僻,當(dāng) Context 改變狀態(tài)時(shí)行為也跟著改變

優(yōu)缺點(diǎn):

減少代碼體積庄拇,利于拓展:狀態(tài)模式可以消除繁雜的條件判斷語句塊,使得業(yè)務(wù)邏輯清晰韭邓,很好地應(yīng)對(duì)對(duì)象狀態(tài)的增加措近、刪除的業(yè)務(wù)場(chǎng)景,因?yàn)樘砑有碌臓顟B(tài)只需要增加新的狀態(tài)類就好了女淑;

狀態(tài)模式狀態(tài)很多時(shí)會(huì)導(dǎo)致狀態(tài)類比較多瞭郑,子類太多的時(shí)候就不方便維護(hù)管理了

應(yīng)用場(chǎng)景:

行為隨狀態(tài)改變而改變的場(chǎng)景;

化繁為簡(jiǎn)鸭你,如果代碼中包含大量的條件語句塊比如 switch…case屈张、if 等,這些語句塊的出現(xiàn)會(huì)導(dǎo)致業(yè)務(wù)邏輯變更時(shí)代碼塊也會(huì)變更苇本,對(duì)狀態(tài)的增加袜茧、刪除時(shí)的調(diào)整修改起來比較吃力時(shí)就可以考慮狀態(tài)模式

4.8.空對(duì)象模式——包攬驗(yàn)證

在空對(duì)象模式(Null Object Pattern)中,一個(gè)空對(duì)象取代 NULL 對(duì)象實(shí)例的檢查

英文定義:Provide an object as a surrogate for the lack of an object of a given type. The Null Object provides intelligent do nothing behavior, hiding the details from its collaborators.

中文定義:為缺少的對(duì)象提供一個(gè)默認(rèn)的無意義對(duì)象瓣窄,用來避免 Null 對(duì)象的產(chǎn)生。就是用一個(gè)空對(duì)象纳鼎,來取代程序中的 Null 值判斷俺夕,從而讓調(diào)用者可以直接使用對(duì)象,而無需關(guān)心對(duì)象是否為 Null

組成角色:

抽象對(duì)象(Abstract Object)角色:聲明統(tǒng)一的對(duì)象行為(屬性和方法)贱鄙;

具體對(duì)象(Concrete Object)角色:確實(shí)存在的具體對(duì)象劝贸,程序中的非 Null 對(duì)象;

空對(duì)象(Null Object)角色:非具體存在的對(duì)象逗宁,Null 對(duì)象映九;

對(duì)象工廠(Object Factory)角色:根據(jù)傳遞的標(biāo)識(shí)得到相關(guān)類的工廠類,返回值可以是具體對(duì)象或 Null 對(duì)象

優(yōu)缺點(diǎn):

優(yōu)點(diǎn)

省去代碼中對(duì) Null 值的判斷和檢查瞎颗;

讓代碼顯的更加優(yōu)雅和可讀性更高件甥;

讓系統(tǒng)更加穩(wěn)定捌议,避免程序拋出 NullPointerException 異常

缺點(diǎn)

因?yàn)樵黾恿烁嗟念愋畔ⅲ瑥亩瓜到y(tǒng)更復(fù)雜

應(yīng)用場(chǎng)景:JDK8中的Optional 對(duì)象使用的就是空對(duì)象模式引有,避免空指針的異常瓣颅。該類中有以下幾個(gè)重要的方法

ofNullable () 方法:為指定的值創(chuàng)建一個(gè) Optional, 如果指定的值為 null,則返回一個(gè)空的 Optional 對(duì)象譬正;

orElse () 方法:如果有值則將其返回宫补,否則返回指定的其它值;

map () 方法:如果創(chuàng)建的 Optional 中的值存在曾我,對(duì)該值執(zhí)行提供的 Function 函數(shù)調(diào)用粉怕;

flagMap () 方法:如果創(chuàng)建的 Optional 中的值存在,就對(duì)該值執(zhí)行提供的 Function 函數(shù)調(diào)用抒巢,返回一個(gè) Optional 類型的值贫贝,否則就返回一個(gè)空的 Optional 對(duì)象

4.9.策略模式——隨機(jī)應(yīng)變

英文定義:Strategy Pattern:Define a family of algorithms,encapsulate each one,and make them interchangeable.

中文定義:定義一組算法,然后將這些算法封裝起來虐秦,以便它們之間可以互換平酿,屬于一種對(duì)象行為型模式

組成角色

上下文角色(Context):該角色一般是一個(gè)實(shí)現(xiàn)類或者封裝類,起到一定的封裝及隔離作用悦陋,實(shí)際接受請(qǐng)求并將請(qǐng)求委托給實(shí)際的算法實(shí)現(xiàn)類處理蜈彼,避免外界對(duì)底層策略的直接訪問;

抽象策略角色(Strategy):該角色一般是一個(gè)抽象角色俺驶,為接口或者抽象類扮演幸逆,定義具體策略角色的公共接口;

具體策略角色(ConcreteStrategy):實(shí)現(xiàn)抽象策略角色的接口暮现,為策略的具體實(shí)現(xiàn)類

優(yōu)缺點(diǎn)

優(yōu)點(diǎn)

所有策略放入一組抽象策略接口中还绘,方便統(tǒng)一管理與實(shí)現(xiàn)

缺點(diǎn)

策略模式每種策略都是單獨(dú)類,策略很多時(shí)策略實(shí)現(xiàn)類也很可觀栖袋;

客戶端初始化 Context 的時(shí)候需要指定策略類拍顷,這樣就要求客戶端要熟悉各個(gè)策略,對(duì)調(diào)用方要求較高

應(yīng)用場(chǎng)景

需要自由切換算法的場(chǎng)景

需要屏蔽算法實(shí)現(xiàn)細(xì)節(jié)的場(chǎng)景

4.10.模板模式——復(fù)制創(chuàng)新

模板模式(Template Pattern)又被稱作模板方法模式(Template Method Pattern)

英文定義:Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm’s structure.

中文定義:定義一個(gè)操作中的算法的框架塘幅,而將一些步驟延遲到子類中昔案。使得子類可以不改變一個(gè)算法的結(jié)構(gòu)即可重定義該算法的某些特定步驟。簡(jiǎn)單來說电媳,就是為子類設(shè)計(jì)一個(gè)模板踏揣,以便在子類中可以復(fù)用這些方法。

組成角色:

抽象模板(Abstract Template)角色:該角色定義一個(gè)或多個(gè)抽象操作匾乓,以便讓子類實(shí)現(xiàn);這些抽象操作是基本操作,是一個(gè)頂級(jí)邏輯的組成步驟彰亥,該角色還需要定義一個(gè)或幾個(gè)模板方法

具體模板(Concrete Template)角色:該角色實(shí)現(xiàn)抽象模板中定義的一個(gè)或多個(gè)抽象方法铃辖,每一個(gè)抽象模板角色都可以有任意多個(gè)具體模板角色與之對(duì)應(yīng)剩愧,而每一個(gè)具體模板角色都可以給出這些抽象方法的不同實(shí)現(xiàn)娇斩,從而使得頂級(jí)邏輯的實(shí)現(xiàn)各不相同。

模板模式中犬第,方法分為兩類:

模板方法

基本方法:

抽象方法:一個(gè)抽象方法由抽象類聲明锦积,由具體子類實(shí)現(xiàn)丰介。在 Java 語言里抽象方法以 abstract 關(guān)鍵字聲明鉴分;

具體方法:一個(gè)具體方法由抽象類聲明并實(shí)現(xiàn)志珍,而子類并不能修改或重寫,此方法通常會(huì)被聲明為 final柜某;

鉤子方法:在抽象類中預(yù)留一個(gè) “鉤子”喂击,也就是實(shí)現(xiàn)一個(gè)空方法翰绊,作為方法的默認(rèn)實(shí)現(xiàn)旁壮,子類可以選擇重寫(重新構(gòu)建)或者不重寫

優(yōu)缺點(diǎn)

優(yōu)點(diǎn)

提高了代碼的復(fù)用性,將相同部分的代碼放在抽象的父類中懈词;

提高了拓展性:將不同的代碼放入不同的子類中,通過對(duì)子類的擴(kuò)展增加新的行為厦坛;

符合開閉原則:行為由父類控制杜秸,通過子類擴(kuò)展新的行為

缺點(diǎn)

每個(gè)不同的行為都要新增一個(gè)子類來完成,抽象類中的抽象方法越多诞挨,子類增加成本就越高惶傻。而且新增的子類越多其障,系統(tǒng)就越復(fù)雜

應(yīng)用場(chǎng)景

多個(gè)子類有公共方法,并且邏輯基本相同時(shí)蜈敢;

可以把重要的抓狭、復(fù)雜的殊橙、核心算法設(shè)計(jì)為模板方法,其他的相關(guān)細(xì)節(jié)功能則由各個(gè)子類實(shí)現(xiàn)叠纹;

重構(gòu)時(shí)誉察,模板方法模式是一個(gè)經(jīng)常使用的模式持偏,把相同的代碼抽取到父類中鸿秆,然后通過鉤子函數(shù)約束其行為

4.11.訪問者模式——另尋他主

英文定義:Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates.

中文定義:封裝一些作用于某種數(shù)據(jù)結(jié)構(gòu)中的各元素的操作卿叽,它可以在不改變數(shù)據(jù)結(jié)構(gòu)的前提下定義作用于這些元素的新的操作。簡(jiǎn)單地來說贩虾,就是將數(shù)據(jù)結(jié)構(gòu)和數(shù)據(jù)操作相分離

組成角色:

訪問者(Visitor):定義對(duì)不同的元素進(jìn)行訪問時(shí)的抽象行為缎罢,一般來說策精,有多少個(gè)具體元素蛮寂,就有多少個(gè)抽象接口酬蹋;

具體訪問者(ConcreteVisitor):實(shí)現(xiàn)上面 Visitor 定義的所有接口范抓,用來指定該訪問者對(duì)各個(gè)元素進(jìn)行訪問時(shí)的具體行為食铐,在本文中由 Root 用戶和普通用戶扮演該角色虐呻;

元素(Element):抽象的被訪問的元素斟叼,一般會(huì)定義一個(gè) accept 方法朗涩,指定其被訪問時(shí)的抽象行為谢床;

具體元素(ConcreteElement):具體的被訪問的元素识腿,實(shí)現(xiàn)上面 Element 的 accept 方法渡讼,各個(gè)元素負(fù)責(zé)定義自己的 accept 行為费薄,來表示其被訪問時(shí)的行為,本文中由 FileElement 和 DictionaryElement 類扮演析藕;

對(duì)象結(jié)構(gòu)(ObjectStructure):對(duì)象結(jié)構(gòu)實(shí)際上是一個(gè)被訪問元素的集合账胧,好比一個(gè)元素容器治泥,對(duì)容器的具體元素的訪問表現(xiàn)出的行為如何居夹,這是由訪問者模式?jīng)Q定的

優(yōu)缺點(diǎn)

優(yōu)點(diǎn)

數(shù)據(jù)結(jié)構(gòu)和數(shù)據(jù)操作相分離准脂;

對(duì)訪問者拓展性良好狸膏,只需要增加新的訪問者類即可湾戳;

各個(gè)角色職責(zé)明確广料,符合單一職責(zé)原則

缺點(diǎn)

元素變更時(shí)會(huì)導(dǎo)致整個(gè)代碼都要調(diào)整

應(yīng)用場(chǎng)景:

對(duì)象的結(jié)構(gòu)(元素)比較穩(wěn)定性昭,而訪問者頻繁變動(dòng)的場(chǎng)景糜颠;

數(shù)據(jù)操作和數(shù)據(jù)結(jié)構(gòu)分離的場(chǎng)景

五其兴、J2EE模式

5.1.MVC模式——合作共贏

MVC 全稱是 Model-View-Controller(模型 - 視圖 - 控制器) 元旬,是一種軟件設(shè)計(jì)典范,用一種業(yè)務(wù)邏輯耗帕、數(shù)據(jù)仿便、界面進(jìn)行分離的開發(fā)模式

組成角色:

Model(模型):用于存儲(chǔ)和操作數(shù)據(jù)(庫)的類嗽仪,可以是存儲(chǔ)容器闻坚,也可以帶有邏輯窿凤,用于返回結(jié)果給控制器卷玉;

View(視圖):展示給用戶的界面相种,用于展示和操作寝并;

Controller(控制器):用于連接模型層和視圖層的中間控制器

優(yōu)缺點(diǎn)

優(yōu)點(diǎn)

分工明確:有利于團(tuán)隊(duì)開發(fā)分工協(xié)作和質(zhì)量控制衬潦,降低開發(fā)成本镀岛;

耦合性低:模塊間相互比較獨(dú)立漂羊,比如走越,在業(yè)務(wù)流程和交互方式不變的情況下耻瑟,可以任意調(diào)整前端頁面的樣式赏酥,而不影響其他模塊裸扶;

重用性高:以模型層來說姓言,可以提供給多個(gè)控制器來使用

缺點(diǎn)

增加了系統(tǒng)實(shí)現(xiàn)的復(fù)雜性,對(duì)于簡(jiǎn)單的應(yīng)用并不適用猪杭;

減低了系統(tǒng)的運(yùn)行性能皂吮,因?yàn)槌绦虻膱?zhí)行經(jīng)過的層數(shù)過多蜂筹,所以會(huì)帶來一定的性能損耗

應(yīng)用場(chǎng)景

Web 開發(fā)領(lǐng)域:由于 Web 開發(fā)的特殊性艺挪,采用 MVC 進(jìn)行結(jié)構(gòu)劃分麻裳,一方面會(huì)提升團(tuán)隊(duì)的協(xié)同開發(fā)效率,專人干專事疆瑰,另一方面也有利于日后軟件產(chǎn)品的維護(hù)和升級(jí)穆役,同時(shí)能夠提升軟件模塊的復(fù)用性孵睬;

移動(dòng)互聯(lián)開發(fā):目前移動(dòng)互聯(lián)開發(fā)掰读,比如:Android蹈集、iOS 開發(fā)也在采用 MVC 框架拢肆,對(duì)于這種展示層修改頻率比較高的應(yīng)用郭怪,采用 MVC 的方式鄙才,使得修改展示層更加的高效攒庵;

實(shí)用型工具類程序:與前兩種開發(fā)不同浓冒,實(shí)用型工具類程序稳懒,更多修改的是展示層之外的代碼僚祷,這種在不更改用戶操作習(xí)慣的方式下辙谜,靜默地調(diào)整和升級(jí)代碼的方式装哆,也比較適合用 MVC 設(shè)計(jì)模式

5.2.業(yè)務(wù)代表模式——各司其職

定義:

業(yè)務(wù)代表模式(Business Delegate Pattern)主要是為了實(shí)現(xiàn)表現(xiàn)層和業(yè)務(wù)層的解耦蜕琴,使用業(yè)務(wù)代表模式可以支持各種場(chǎng)景

組成角色

客戶端(Client):表現(xiàn)層上炎,可以是 JSP藕施、Servlet 或者 Java 代碼裳食。上面的例子中指的就是去銀行辦理業(yè)務(wù)的客戶诲祸;

業(yè)務(wù)代表(Business Delegate):和客戶端打交道的實(shí)體類救氯,提供了對(duì)業(yè)務(wù)服務(wù)方法的訪問着憨。對(duì)應(yīng)的是業(yè)務(wù)顧問享扔;

查詢服務(wù)(Look Up Service):用來查詢具體業(yè)務(wù)范疇或?qū)ο蟮木唧w業(yè)務(wù)實(shí)現(xiàn)惧眠,對(duì)應(yīng)上文的就是業(yè)務(wù)顧問要根據(jù)查詢服務(wù)查詢對(duì)客戶進(jìn)行服務(wù)的具體窗口(服務(wù)實(shí)現(xiàn))氛魁;

業(yè)務(wù)服務(wù)(Business Service):具體的業(yè)務(wù)服務(wù)實(shí)現(xiàn)類秀存,對(duì)應(yīng)的就是具體的服務(wù)窗口

優(yōu)缺點(diǎn)

表現(xiàn)層和業(yè)務(wù)層分離或链,利于應(yīng)用解耦澳盐;

客戶端可以根據(jù)需要自主選擇業(yè)務(wù)代表叼耙,符合面向?qū)ο蟮奶攸c(diǎn)

應(yīng)用場(chǎng)景

業(yè)務(wù)的表現(xiàn)層和業(yè)務(wù)層解耦:傳統(tǒng)的 MVC 架構(gòu)中筛婉,為了實(shí)現(xiàn) JSP爽撒、Servlet 等與業(yè)務(wù)層解耦安寺,可以提高系統(tǒng)的開發(fā)效率以及模塊的復(fù)用性

5.3.傳輸對(duì)象模式——對(duì)象傳遞

定義:

傳輸對(duì)象模式(Transfer Object Pattern)是指客戶端到服務(wù)器一次性傳遞具有多個(gè)屬性的數(shù)據(jù)挑庶,以避免多次調(diào)用遠(yuǎn)程服務(wù)器

組成角色

傳輸對(duì)象(Transfer Object):簡(jiǎn)單的實(shí)體類迎捺,只有 getter/setter 方法凳枝;

業(yè)務(wù)對(duì)象(Business Object):為客戶端提供業(yè)務(wù)數(shù)據(jù),用于數(shù)據(jù)處理和構(gòu)建傳輸對(duì)象蹋订;

客戶端(Client):發(fā)送請(qǐng)求或者發(fā)送傳輸對(duì)象到業(yè)務(wù)對(duì)象

優(yōu)缺點(diǎn)

優(yōu)點(diǎn)

減少了遠(yuǎn)程調(diào)用次數(shù):通過在單個(gè)遠(yuǎn)程調(diào)用中傳輸更多的數(shù)據(jù)露戒,應(yīng)用程序可以減少遠(yuǎn)程調(diào)用次數(shù);

提高了性能:遠(yuǎn)程調(diào)用可以使應(yīng)用程序的運(yùn)行速度大大降低荠锭,減少調(diào)用次數(shù)是提高性能的最佳方法之一节沦;

簡(jiǎn)化了程序代碼:使用傳輸對(duì)象的模式使代碼可讀性更高甫贯,讓程序看起來更簡(jiǎn)單

缺點(diǎn)

增加了復(fù)雜性:由于要兼容多個(gè)版本的程序叫搁,可能需要?jiǎng)?chuàng)建更多的實(shí)體類來適用各個(gè)版本的程序疾党,這會(huì)讓程序變得更加復(fù)雜

應(yīng)用場(chǎng)景

希望減少程序中遠(yuǎn)程調(diào)用次數(shù)雪位;

希望提高程序獲取資源的性能雹洗;

程序需要傳輸多個(gè)數(shù)據(jù)時(shí)

5.4.數(shù)據(jù)訪問對(duì)象模式——去偽存真

定義:數(shù)據(jù)訪問對(duì)象模式(Data Access Object Pattern)又稱為 DAO 模式,是一種面向?qū)ο蟮臄?shù)據(jù)訪問接口螃成,DAO 一般都是和數(shù)據(jù)庫打交道寸宏,屬于業(yè)務(wù)邏輯和數(shù)據(jù)庫中間的環(huán)節(jié)击吱,負(fù)責(zé)業(yè)務(wù)邏輯數(shù)據(jù)的持久化

組成角色:

數(shù)據(jù)訪問對(duì)象接口(Data Access Object Interface):提供數(shù)據(jù)持久化或數(shù)據(jù)訪問的抽象接口定義朵纷;

數(shù)據(jù)訪問對(duì)象具體實(shí)現(xiàn)類(Data Access Object Concrete Class):負(fù)責(zé)實(shí)現(xiàn)數(shù)據(jù)訪問對(duì)象接口袍辞,真正對(duì)數(shù)據(jù)進(jìn)行操作的實(shí)現(xiàn)類搅吁,底層數(shù)據(jù)源可以是數(shù)據(jù)庫谎懦、內(nèi)存肚豺、Xml、文件數(shù)據(jù)等等界拦;

模型對(duì)象或值對(duì)象(Model Object/Value Object):傳統(tǒng)的 POJO(Plain Ordinary Java Object)吸申,可以理解為簡(jiǎn)單的實(shí)體類

優(yōu)缺點(diǎn)

優(yōu)點(diǎn)

業(yè)務(wù)層和數(shù)據(jù)持久層分離,減輕系統(tǒng)耦合度;

數(shù)據(jù)訪問對(duì)象單獨(dú)抽離出來截碴,可以適配各種底層持久化類型,提高系統(tǒng)的拓展性

缺點(diǎn)

每添加一個(gè)實(shí)體類日丹,就必須添加一套 DAO 接口和一套 DAO 實(shí)現(xiàn)類走哺,會(huì)導(dǎo)致代碼重復(fù)臃腫

應(yīng)用場(chǎng)景

DAO 的引入,幫助我們實(shí)現(xiàn)對(duì)持久化層的操作哲虾,只關(guān)心業(yè)務(wù)邏輯丙躏;

一切和持久化層打交道的應(yīng)用場(chǎng)景都會(huì)感受到數(shù)據(jù)訪問對(duì)象模式的影子,有數(shù)據(jù)訪問就會(huì)有 DAO 的存在

5.5.前端控制器模式——集中控制

定義:前端控制器模式(Front Controller Pattern)妒牙,是提供一種可以集中式管理請(qǐng)求的控制器彼哼,控制器把所有的用戶請(qǐng)求進(jìn)行統(tǒng)一的管理和分配

組成角色:

前端控制器(Front Controller):提供應(yīng)用程序的統(tǒng)一請(qǐng)求入口,這個(gè)應(yīng)用程序可以是 Web 程序湘今,也可以是基于桌面的應(yīng)用程序敢朱;

調(diào)度器(Dispatcher):它的作用是把請(qǐng)求調(diào)度到相應(yīng)的處理程序,前端控制器可以調(diào)用一個(gè)或多個(gè)調(diào)度器來完成請(qǐng)求分發(fā)摩瞎;

視圖(View):用來展示和響應(yīng)用戶的界面

優(yōu)缺點(diǎn)

優(yōu)點(diǎn)

集中控制:前端控制器為所有請(qǐng)求提供了統(tǒng)一入口拴签,這樣就完成了集中請(qǐng)求控制;

提高了代碼的復(fù)用率:不用在每個(gè)頁面單獨(dú)進(jìn)行權(quán)限驗(yàn)證或日志記錄旗们,而是提供了統(tǒng)一的處理代碼蚓哩,提高了代碼的復(fù)用率;

維護(hù)成本更低:因?yàn)樘峁┝舜a的統(tǒng)一處理上渴,所以需要改動(dòng)的代碼就更少岸梨,對(duì)應(yīng)的維護(hù)成本也更低;

職責(zé)分工明確:因?yàn)樘峁┝私y(tǒng)一的權(quán)限驗(yàn)證和日志記錄等稠氮,所以之后的頁面可以更專注地處理自己本身的業(yè)務(wù)曹阔,角色之間的分工也更明確

缺點(diǎn)

增加了系統(tǒng)復(fù)雜度:因?yàn)椴皇侵苯佑|到,所以增加了系統(tǒng)的復(fù)雜性隔披,對(duì)新手來說更是如此赃份;

降低了程序運(yùn)行速度:因?yàn)樘峁┝私y(tǒng)一的權(quán)限判斷,所以相比于直接請(qǐng)求的方式奢米,統(tǒng)一的攔截和調(diào)度會(huì)降低程序的運(yùn)行速度

應(yīng)用場(chǎng)景

統(tǒng)一的權(quán)限處理

統(tǒng)一的日志記錄

統(tǒng)一的邏輯處理

5.6.攔截過濾器模式——法無二門

定義:攔截過濾器模式(Intercepting Filter Pattern)是一種普遍應(yīng)用的模式抓韩,該模式提供對(duì)應(yīng)用程序請(qǐng)求前后進(jìn)行一些預(yù)處理攔截,比如日志打印鬓长、權(quán)限攔截等谒拴,Web 開發(fā)中使用非常普遍

組成角色:

過濾器(Filter):負(fù)責(zé)對(duì)請(qǐng)求進(jìn)行過濾處理的實(shí)際類,在請(qǐng)求前后執(zhí)行一些邏輯調(diào)用涉波;

過濾器鏈(Filter Chain):過濾器組成的集合彪薛,另外該角色還包括一個(gè)被過濾的目標(biāo)對(duì)象茂装,指定該對(duì)象被哪些過濾器攔截;

目標(biāo)對(duì)象(Target):實(shí)際被過濾或者請(qǐng)求調(diào)用的業(yè)務(wù)模塊善延,是客戶端實(shí)際需要請(qǐng)求的資源載體少态;

過濾管理器(Filter Manager):用來管理過濾器鏈的實(shí)際類,包括對(duì)過濾器鏈中過濾器的管理和目標(biāo)對(duì)象的管理易遣;

客戶端(Client):實(shí)際向目標(biāo)對(duì)象發(fā)出請(qǐng)求的對(duì)象

優(yōu)缺點(diǎn)

優(yōu)點(diǎn)

對(duì)目標(biāo)對(duì)象的請(qǐng)求優(yōu)先經(jīng)過過濾器處理彼妻,可以有效保護(hù)目標(biāo)資源,比如一些權(quán)限過濾器豆茫、編解碼過濾器侨歉、黑白名單攔截等;

攔截過濾器模式讓我們可以流式處理各種請(qǐng)求揩魂,有利于模塊解耦幽邓,支持可插拔設(shè)計(jì)

缺點(diǎn)

過濾器太多會(huì)導(dǎo)致出現(xiàn)問題不好定位,另外過多的過濾器也會(huì)加劇請(qǐng)求時(shí)長(zhǎng)

應(yīng)用場(chǎng)景

執(zhí)行目標(biāo)資源請(qǐng)求時(shí)的一些預(yù)處理工作火脉,比如編碼設(shè)置牵舵、數(shù)據(jù)解密,一般這類過濾器會(huì)選擇對(duì)請(qǐng)求直接放行倦挂;

執(zhí)行應(yīng)用的安全控制畸颅、日志記錄等工作,可以使用過濾器進(jìn)行方援,當(dāng)然日志記錄也可以使用切面配合自定義注解實(shí)現(xiàn)没炒;

對(duì)請(qǐng)求的一些后置處理,比如返回格式轉(zhuǎn)換犯戏、響應(yīng)時(shí)長(zhǎng)記錄等送火。這些過濾器一般都是在請(qǐng)求結(jié)束后進(jìn)行的

5.7.服務(wù)定位器模式——緩存增速

定義:

服務(wù)定位模式(Service Locator Pattern)是為服務(wù)調(diào)用者提供一個(gè)注冊(cè)中心(統(tǒng)一調(diào)用入口),把具體相關(guān)的服務(wù)注冊(cè)到服務(wù)中心先匪,這個(gè)注冊(cè)中心被稱為服務(wù)定位器漾脂。在首次請(qǐng)求某個(gè)服務(wù)時(shí),服務(wù)定位器會(huì)查找服務(wù)胚鸯,沒有已經(jīng)存在的服務(wù),會(huì)新建并緩存該服務(wù)對(duì)象笨鸡。當(dāng)再次請(qǐng)求相同的服務(wù)時(shí)姜钳,服務(wù)定位器會(huì)在它的緩存中查找,這樣可以在很大程度上提高應(yīng)用程序的性能形耗。

組成角色:

服務(wù)(Service):實(shí)際處理請(qǐng)求的服務(wù)(類)哥桥;

上下文對(duì)象(Context):為服務(wù)定位器提供要獲取的服務(wù)類(Service)。

服務(wù)定位器(Service Locator):獲取服務(wù)的統(tǒng)一入口激涤,為客戶端提供緩存或非緩存服務(wù)類拟糕。

緩存(Cache):緩存服務(wù)對(duì)象判呕,以便下次調(diào)用時(shí)直接復(fù)用;

客戶端(Client):服務(wù)調(diào)用者送滞,通過服務(wù)定位器調(diào)用服務(wù)對(duì)象

優(yōu)缺點(diǎn)

優(yōu)點(diǎn)

解耦服務(wù)提供者和服務(wù)調(diào)用者侠草;

更好地?cái)U(kuò)展和升級(jí),例如犁嗅,當(dāng)更換服務(wù)提供者算法時(shí)边涕,客戶端調(diào)用者是無感知的;

使用緩存類提高了程序執(zhí)行性能

缺點(diǎn)

增加了出現(xiàn)問題的幾率:由于提供了統(tǒng)一的定位器褂微,而隱藏了類的依賴關(guān)系功蜓,讓本來可以在編譯期暴露的問題,在運(yùn)行時(shí)才能被發(fā)現(xiàn)宠蚂;

增加了排查問題的難度:服務(wù)調(diào)用者無法確切地知道服務(wù)提供者的真實(shí)情況式撼,如果遇到問題很難排除

應(yīng)用場(chǎng)景

根據(jù) JNDI(Java Naming and Directory Interface,Java 命名與目錄接口)查詢定位各種服務(wù)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末求厕,一起剝皮案震驚了整個(gè)濱河市著隆,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌甘改,老刑警劉巖旅东,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異十艾,居然都是意外死亡抵代,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門忘嫉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來荤牍,“玉大人,你說我怎么就攤上這事庆冕】党常” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵访递,是天一觀的道長(zhǎng)晦嵌。 經(jīng)常有香客問我,道長(zhǎng)拷姿,這世上最難降的妖魔是什么惭载? 我笑而不...
    開封第一講書人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮响巢,結(jié)果婚禮上描滔,老公的妹妹穿的比我還像新娘。我一直安慰自己踪古,他們只是感情好含长,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開白布券腔。 她就那樣靜靜地躺著,像睡著了一般拘泞。 火紅的嫁衣襯著肌膚如雪纷纫。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,688評(píng)論 1 305
  • 那天田弥,我揣著相機(jī)與錄音涛酗,去河邊找鬼。 笑死偷厦,一個(gè)胖子當(dāng)著我的面吹牛商叹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播只泼,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼剖笙,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了请唱?” 一聲冷哼從身側(cè)響起弥咪,我...
    開封第一講書人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎十绑,沒想到半個(gè)月后聚至,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡本橙,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年扳躬,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片甚亭。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡贷币,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出亏狰,到底是詐尸還是另有隱情役纹,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布暇唾,位于F島的核電站促脉,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏策州。R本人自食惡果不足惜瘸味,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望抽活。 院中可真熱鬧,春花似錦锰什、人聲如沸下硕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽梭姓。三九已至霜幼,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間誉尖,已是汗流浹背罪既。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留铡恕,地道東北人琢感。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像探熔,于是被迫代替她去往敵國(guó)和親驹针。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355