Spring框架中的設(shè)計模式(二)

上一篇中我們在Spring中所談到的設(shè)計模式涉及到了創(chuàng)建模式三劍客和1個行為模式(解釋器模式)。這次我們會將眼光更多地關(guān)注在具有結(jié)構(gòu)性和行為性的設(shè)計模式上。

在這篇文章中,我們將看到每個類型的兩種模式。首先將關(guān)注類型是的結(jié)構(gòu)設(shè)計模式。它將包含代理和復(fù)合。下一個將介紹行為模式:策略和模板方法。






代理模式

面向?qū)ο缶幊蹋∣OP)可能是編程中最流行的概念。然而,Spring引入了另一種編碼規(guī)范,面向切面編程(AOP)。為了簡化定義,AOP是面向系統(tǒng)特定點的一種編程,如:異常拋出,特定類別方法的執(zhí)行等.AOP允許在執(zhí)行這些特定點之前或之后執(zhí)行補充動作。如何實現(xiàn)這種操作?它可以通過監(jiān)聽器(listeners)進行。但在這種情況下,我們應(yīng)該在只要可能存在調(diào)用的地方都需要定義監(jiān)聽器來進行監(jiān)聽(比如在一個方法的開始的地方)。這就是為什么Spring不采用這個idea。相反,Spring實現(xiàn)了一種能夠通過額外的方法調(diào)用完成任務(wù)的設(shè)計模式 -代理設(shè)計模式

代理就像對象的鏡像一樣。也正因為如此,代理對象不僅可以覆蓋真實對象,還可以擴展其功能。因此,對于只能在屏幕上打印一些文本的對象,我們可以添加另一個對象來過濾顯示單詞??梢酝ㄟ^代理來定義第二個對象的調(diào)用。代理是封裝真實對象的對象。例如,如果您嘗試調(diào)用Waiter bean,那么您將調(diào)用該Bean的代理,其行為方式完全相同。

代理設(shè)計模式的一個很好的例子是org.springframework.aop.framework.ProxyFactoryBean。該工廠根據(jù)Spring bean構(gòu)建AOP代理。該類實現(xiàn)了定義getObject()方法的FactoryBean接口。此方法用于將需求Bean的實例返回給bean factory。在這種情況下,它不是返回的實例,而是AOP代理。在執(zhí)行代理對象的方法之前,可以通過調(diào)用補充方法來進一步“修飾”代理對象(其實所謂的靜態(tài)代理不過是在裝飾模式上加了個要不要你來干動作行為而已,而不是裝飾模式什么也不做就加了件衣服,其他還得由你來全權(quán)完成)。

ProxyFactory的一個例子是:

這個測試應(yīng)該通過,因為我們不直接在House實例上操作,而是代理它。代理調(diào)用第一個 BeforeConstructAdvice的 before方法(指向在執(zhí)行目標(biāo)方法之前執(zhí)行,在我們的例子中為 construct())通過它,給出了一個“權(quán)限”來構(gòu)造對象的字段(house)。代理層提供了一個額外新功能,因為它可以簡單地分配給另一個對象。要做到這一點,我們只能在before方法之前修改過濾器。





復(fù)合模式

另一種結(jié)構(gòu)模式是復(fù)合模式。在關(guān)于Spring中設(shè)計模式的第一篇文章中,我們使用構(gòu)建器來構(gòu)造復(fù)雜對象。另一種實現(xiàn)方法是使用復(fù)合模式。這種模式是基于具有共同行為的多個對象的存在,用于構(gòu)建更大的對象。較大的對象仍然具有與最小對象相同的特征。那么用它來定義相同的行為。

復(fù)合對象的非Spring示例可以是一個寫入HTML的文本對象,由包含span或em標(biāo)簽的段落組成:

在這種情況下,可以看到一個復(fù)合對象。我們可以區(qū)分復(fù)合與非復(fù)合對象,因為第一個可以容納一個或多個非復(fù)合對象(PTag類中的privateListtags字段)。非復(fù)合對象稱為葉子。TextTag接口被稱為組件,因為它為兩個對象類型提供了共同的行為規(guī)范(有點像Linux文件管理系統(tǒng)的有共同點的文件放在一個文件夾下進行管理,其實就是節(jié)點管理)。

在Spring世界中,我們檢索復(fù)合對象的概念是org.springframework.beans.BeanMetadataElement接口,用于配置bean對象。它是所有繼承對象的基本界面?,F(xiàn)在,在一方面,我們有一個葉子,由org.springframework.beans.factory.parsing.BeanComponentDefinition表示,另一邊是復(fù)合org.springframework.beans.factory.parsing.CompositeComponentDefinition。CompositeComponentDefinition類似于組件,因為它包含addNestedComponent(ComponentDefinition component)方法,它允許將葉添加到私有final列表中nestedComponents。您可以看到,由于此列表,BeanComponentDefinition和CompositeComponentDefinition的組件是org.springframework.beans.factory.parsing.ComponentDefinition。






策略模式

本文描述的第三個概念是策略設(shè)計模式。策略定義了通過不同方式完成相同事情的幾個對象。完成任務(wù)的方式取決于采用的策略。舉個例子說明,我們可以去一個國家。我們可以乘公共汽車,飛機,船甚至汽車去那里。所有這些方法將把我們運送到目的地國家。但是,我們將通過檢查我們的銀行帳戶來選擇最適應(yīng)的方式。如果我們有很多錢,我們將采取最快的方式(可能是私人飛行)。如果我們沒有足夠的話,我們會采取最慢的(公車,汽車)。該銀行賬戶作為確定適應(yīng)策略的因素。

Spring在org.springframework.web.servlet.mvc.multiaction.MethodNameResolver類(過時,但不影響拿來研究)中使用策略設(shè)計模式。它是MultiActionController(同樣過時)的參數(shù)化實現(xiàn)。在開始解釋策略之前,我們需要了解MultiActionController的實用性。這個類允許同一個類處理幾種類型的請求。作為Spring中的每個控制器,MultiActionController執(zhí)行方法來響應(yīng)提供的請求。策略用于檢測應(yīng)使用哪種方法。解析過程在MethodNameResolver實現(xiàn)中實現(xiàn),例如在同一個包中的ParameterMethodNameResolver中。方法可以通過多個條件解決:屬性映射,HTTP請求參數(shù)或URL路徑。

正如我們在前面的代碼中可以看到的,方法的名稱通過提供的參數(shù)映射,URL中的預(yù)定義屬性或參數(shù)存在來解決(默認(rèn)情況下,該參數(shù)的名稱是action)。





模板模式

本文提出的最后一個設(shè)計模式是模板方法。此模式定義了類行為的骨架,并將子步驟的某些步驟的延遲執(zhí)行(具體就是下面例子中一個方法放在另一個方法中,只有調(diào)用另一方方法的時候這個方法才會執(zhí)行,而且還可能會在其他行為方法之后按順序執(zhí)行)。其中寫了一種方法(下面例子中的construct()),注意定義為final,起著同步器的角色。它以給定的順序執(zhí)行由子類定義的方法。在現(xiàn)實世界中,我們可以將模板方法與房屋建設(shè)進行比較。獨立于建造房屋的公司,我們需要從建立基礎(chǔ)開始,只有在我們完成之后才能做其他的工作。這個執(zhí)行邏輯將被保存在一個我們不能改變的方法中。例如基礎(chǔ)建設(shè)或刷墻會被作為一個模板方法中的方法,具體到建筑房屋的公司。我們可以在給定的例子中看到它:

該代碼應(yīng)該輸出:

Spring在org.springframework.context.support.AbstractApplicationContext類中使用模板方法。他們不是一個模板方法(在我們的例子中是construct ),而是多個。例如,getsFreshBeanFactory返回內(nèi)部bean工廠的新版本,調(diào)用兩個抽象方法:refreshBeanFactory(刷新工廠bean)和getBeanFactory(以獲取更新的工廠bean)。這個方法和其他一些方法一樣,用在public void refresh()中,拋出構(gòu)造應(yīng)用程序上下文的BeansException,IllegalStateException方法(這里會在后面Spring中與應(yīng)用程序上下文分析中再次提到)。

我們可以從同一個包中的GenericApplicationContext找到一些通過模板方法所實現(xiàn)的抽象方法的實現(xiàn)的例子(說的有點拗口,多讀幾遍就好):

經(jīng)過上面這些可以讓我們發(fā)現(xiàn)Spring如何通過使用行為和結(jié)構(gòu)設(shè)計模式來更好地組織上下文(模板方法),并通過相應(yīng)策略來解決執(zhí)行方法。它使用兩種結(jié)構(gòu)設(shè)計模式,通過代理模式來簡化AOP部分并通過復(fù)合模式來構(gòu)造復(fù)雜對象。




原文鏈接:https://mp.weixin.qq.com/s/fc0af9WPlTK_LduChSfLhA

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容