Spring5源碼分析系列(一)從現(xiàn)實(shí)生活理解Spring中常用的設(shè)計(jì)模式

一痹兜、Spring中常用的設(shè)計(jì)模式

1穆咐、我們通常說(shuō)的23種經(jīng)典設(shè)計(jì)模式可以通過(guò)下表一目了然:

通常來(lái)說(shuō),設(shè)計(jì)模式都是混合使用字旭,不會(huì)獨(dú)立應(yīng)用对湃。利用窮舉法充分理解設(shè)計(jì)模式的應(yīng)用場(chǎng)景。在平時(shí)的應(yīng)用中遗淳,不是用設(shè)計(jì)模式去生搬硬套拍柒,而是根據(jù)具體業(yè)務(wù)問(wèn)題需要時(shí)借鑒。

2屈暗、設(shè)計(jì)模式在應(yīng)用中遵循六大原則:

a拆讯、開(kāi)閉原則(OpenClosePrinciple)

開(kāi)閉原則就是說(shuō)對(duì)擴(kuò)展開(kāi)放,對(duì)修改關(guān)閉养叛。在程序需要進(jìn)行拓展的時(shí)候种呐,不能去修改原有的代碼,實(shí)現(xiàn)

一個(gè)熱插拔的效果弃甥。所以一句話概括就是:為了使程序的擴(kuò)展性好爽室,易于維護(hù)和升級(jí)。想要達(dá)到這樣的

效果淆攻,我們需要使用接口和抽象類(lèi)阔墩,后面的具體設(shè)計(jì)中我們會(huì)提到這點(diǎn)。

b瓶珊、里氏代換原則(LiskovSubstitutionPrinciple)

面向?qū)ο笤O(shè)計(jì)的基本原則之一戈擒。里氏代換原則中說(shuō),任何基類(lèi)可以出現(xiàn)的地方艰毒,子類(lèi)一定可以出現(xiàn)筐高。LSP是繼承復(fù)用的基石,只有當(dāng)衍生類(lèi)可以替換掉基類(lèi)丑瞧,軟件單位的功能不受到影響時(shí)柑土,基類(lèi)才能真正被復(fù)用,而衍生類(lèi)也能夠在基類(lèi)的基礎(chǔ)上增加新的行為绊汹。里氏代換原則是對(duì)“開(kāi)-閉”原則的補(bǔ)充稽屏。實(shí)現(xiàn)“開(kāi)-閉”原則的關(guān)鍵步驟就是抽象化。而基類(lèi)與子類(lèi)的繼承關(guān)系就是抽象化的具體實(shí)現(xiàn)西乖,所以里氏代換原則是對(duì)實(shí)現(xiàn)抽象化的具體步驟的規(guī)范狐榔。

c坛增、依賴(lài)倒轉(zhuǎn)原則(DependenceInversionPrinciple)

這個(gè)是開(kāi)閉原則的基礎(chǔ),具體內(nèi)容:針對(duì)接口編程薄腻,依賴(lài)于抽象而不依賴(lài)于具體收捣。

d、接口隔離原則(InterfaceSegregationPrinciple)

這個(gè)原則的意思是:使用多個(gè)隔離的接口庵楷,比使用單個(gè)接口要好罢艾。還是一個(gè)降低類(lèi)之間的耦合度的意思,從這兒我們看出尽纽,其實(shí)設(shè)計(jì)模式就是一個(gè)軟件的設(shè)計(jì)思想咐蚯,從大型軟件架構(gòu)出發(fā),為了升級(jí)和維護(hù)方便弄贿。所以上文中多次出現(xiàn):降低依賴(lài)春锋,降低耦合。

e差凹、迪米特法則(最少知道原則)(DemeterPrinciple)

為什么叫最少知道原則期奔,就是說(shuō):一個(gè)實(shí)體應(yīng)當(dāng)盡量少的與其他實(shí)體之間發(fā)生相互作用,使得系統(tǒng)功能模塊相對(duì)獨(dú)立直奋。

f、合成復(fù)用原則(CompositeReusePrinciple)

原則是盡量使用合成/聚合的方式施禾,而不是使用繼承脚线。

設(shè)計(jì)模式之間的關(guān)系圖:


二:Spring中常用的設(shè)計(jì)模式:

1.1、簡(jiǎn)單工廠模式(Factory)

應(yīng)用場(chǎng)景:又叫做靜態(tài)工廠方法(StaticFactoryMethod)模式弥搞,但不屬于23種設(shè)計(jì)模式之一邮绿。簡(jiǎn)單工廠模式的實(shí)質(zhì)是由一個(gè)工廠類(lèi)根據(jù)傳入的參數(shù),動(dòng)態(tài)決定應(yīng)該創(chuàng)建哪一個(gè)產(chǎn)品類(lèi)攀例。

Spring中的BeanFactory就是簡(jiǎn)單工廠模式的體現(xiàn)船逮,根據(jù)傳入一個(gè)唯一的標(biāo)識(shí)來(lái)獲得Bean對(duì)象,但是否是在傳入?yún)?shù)后創(chuàng)建還是傳入?yún)?shù)前創(chuàng)建這個(gè)要根據(jù)具體情況來(lái)定粤铭。


1.2挖胃、工廠方法模式(FactoryMethod)

應(yīng)用場(chǎng)景:通常由應(yīng)用程序直接使用new創(chuàng)建新的對(duì)象,為了將對(duì)象的創(chuàng)建和使用相分離梆惯,采用工廠模式,即應(yīng)用程序?qū)?duì)象的創(chuàng)建及初始化職責(zé)交給工廠對(duì)象酱鸭。

一般情況下,應(yīng)用程序有自己的工廠對(duì)象來(lái)創(chuàng)建Bean.如果將應(yīng)用程序自己的工廠對(duì)象交給Spring管理,那么Spring

管理的就不是普通的Bean,而是工廠Bean。


1.3垛吗、單例模式(Singleton)

應(yīng)用場(chǎng)景:保證一個(gè)類(lèi)僅有一個(gè)實(shí)例凹髓,并提供一個(gè)訪問(wèn)它的全局訪問(wèn)點(diǎn)。

Spring中的單例模式完成了后半句話怯屉,即提供了全局的訪問(wèn)點(diǎn)BeanFactory蔚舀。但沒(méi)有從構(gòu)造器級(jí)別去控制單例饵沧,這是因?yàn)镾pring管理的是是任意的Java對(duì)象。Spring下默認(rèn)的Bean均為單例赌躺。

常用單例模式寫(xiě)法:餓漢式狼牺、懶漢式、注冊(cè)式寿谴、序列化锁右。


1.4、原型模式(Prototype)

應(yīng)用場(chǎng)景:原型模式就是從一個(gè)對(duì)象再創(chuàng)建另外一個(gè)可定制的對(duì)象讶泰,而且不需要知道任何創(chuàng)建的細(xì)節(jié)咏瑟。

所謂原型模式,就是Java中的克隆技術(shù)痪署,以某個(gè)對(duì)象為原型码泞。復(fù)制出新的對(duì)象。顯然新的對(duì)象具備原型對(duì)象的特點(diǎn)狼犯,效率高(避免了重新執(zhí)行構(gòu)造過(guò)程步驟)余寥。


1.5、代理模式(Proxy)

應(yīng)用場(chǎng)景:為其他對(duì)象提供一種代理以控制對(duì)這個(gè)對(duì)象的訪問(wèn)悯森。從結(jié)構(gòu)上來(lái)看和Decorator模式類(lèi)似宋舷,但Proxy是控制,更像是一種對(duì)功能的限制瓢姻,而Decorator是增加職責(zé)祝蝠。

Spring的Proxy模式在AOP中有體現(xiàn),比如JdkDynamicAopProxy和Cglib2AopProxy幻碱。


1.6绎狭、策略模式(Strategy)

應(yīng)用場(chǎng)景:定義一系列的算法,把它們一個(gè)個(gè)封裝起來(lái)褥傍,并且使它們可相互替換儡嘶。本模式使得算法可獨(dú)

立于使用它的客戶而變化。

Spring中在實(shí)例化對(duì)象的時(shí)候用到Strategy模式恍风,在SimpleInstantiationStrategy有使用蹦狂。


1.7、模板方法模式(TemplateMethod)

定義一個(gè)操作中的算法的骨架朋贬,而將一些步驟延遲到子類(lèi)中鸥咖。TemplateMethod使得子類(lèi)可以不改變一個(gè)算法的結(jié)構(gòu)即可重定義該算法的某些特定步驟。

TemplateMethod模式一般是需要繼承的兄世。這里想要探討另一種對(duì)TemplateMethod的理解啼辣。Spring中的JdbcTemplate,在用這個(gè)類(lèi)時(shí)并不想去繼承這個(gè)類(lèi)御滩,因?yàn)檫@個(gè)類(lèi)的方法太多鸥拧,但是我們還是想用到JdbcTemplate

已有的穩(wěn)定的党远、公用的數(shù)據(jù)庫(kù)連接,那么我們?cè)趺崔k呢富弦?我們可以把變化的東西抽出來(lái)作為一個(gè)參數(shù)傳入JdbcTemplate的方法中沟娱。但是變化的東西是一段代碼,而且這段代碼會(huì)用到JdbcTemplate中的變量腕柜。怎么辦济似?那我們就用回調(diào)對(duì)象吧。在這個(gè)回調(diào)對(duì)象中定義一個(gè)操縱JdbcTemplate中變量的方法盏缤,我們?nèi)?shí)現(xiàn)這個(gè)方法砰蠢,就把變化的東西集中到這里了。然后我們?cè)賯魅脒@個(gè)回調(diào)對(duì)象到JdbcTemplate唉铜,從而完成了調(diào)用台舱。這就是TemplateMethod不需要繼承的另一種實(shí)現(xiàn)方式。


1.8潭流、委派模式(Delegate)

應(yīng)用場(chǎng)景:不屬于23種設(shè)計(jì)模式之一竞惋,是面向?qū)ο笤O(shè)計(jì)模式中常用的一種模式。這種模式的原理為類(lèi)B和類(lèi)A是兩個(gè)互相沒(méi)有任何關(guān)系的類(lèi)灰嫉,B具有和A一模一樣的方法和屬性拆宛;并且調(diào)用B中的方法,屬性就是調(diào)用A中同名的方法和屬性讼撒。B好像就是一個(gè)受A授權(quán)委托的中介浑厚。第三方的代碼不需要知道A的存在,也不需要和A發(fā)生直接的聯(lián)系椿肩,通過(guò)B就可以直接使用A的功能瞻颂,這樣既能夠使用到A的各種功能豺谈,又能夠很好的將A保護(hù)起來(lái)了郑象,一舉兩得。


1.9茬末、適配器模式(Adapter)

SpringAOP模塊對(duì)BeforeAdvice厂榛、AfterAdvice、ThrowsAdvice三種通知類(lèi)型的支持實(shí)際上是借助適配器模式來(lái)實(shí)現(xiàn)的丽惭,這樣的好處是使得框架允許用戶向框架中加入自己想要支持的任何一種通知類(lèi)型击奶,上述三種通知類(lèi)型是SpringAOP模塊定義的,它們是AOP聯(lián)盟定義的Advice的子類(lèi)型责掏。


1.10柜砾、裝飾器模式(Decorator)

應(yīng)用場(chǎng)景:在我們的項(xiàng)目中遇到這樣一個(gè)問(wèn)題:我們的項(xiàng)目需要連接多個(gè)數(shù)據(jù)庫(kù),而且不同的客戶在每

次訪問(wèn)中根據(jù)需要會(huì)去訪問(wèn)不同的數(shù)據(jù)庫(kù)换衬。我們以往在Spring和Hibernate框架中總是配置一個(gè)數(shù)據(jù)源痰驱,因而SessionFactory的DataSource屬性總是指向這個(gè)數(shù)據(jù)源并且恒定不變证芭,所有DAO在使用SessionFactory的時(shí)候都是通過(guò)這個(gè)數(shù)據(jù)源訪問(wèn)數(shù)據(jù)庫(kù)。但是現(xiàn)在担映,由于項(xiàng)目的需要废士,我們的DAO在訪問(wèn)SessionFactory的時(shí)候都不得不在多個(gè)數(shù)據(jù)源中不斷切換,問(wèn)題就出現(xiàn)了:如何讓SessionFactory在執(zhí)行數(shù)據(jù)持久化的時(shí)候蝇完,根據(jù)客戶的需求能夠動(dòng)態(tài)切換不同的數(shù)據(jù)源官硝?我們能不能在Spring的框架下通過(guò)少量修改得到解決?是否有什么設(shè)計(jì)模式可以利用呢短蜕?

首先想到在Spring的ApplicationContext中配置所有的DataSource氢架。這些DataSource可能是各種不同類(lèi)型的,比如不同的數(shù)據(jù)庫(kù):Oracle忿危、SQLServer达箍、MySQL等,也可能是不同的數(shù)據(jù)源:比如Apache提供的org.apache.commons.dbcp.BasicDataSource铺厨、Spring提供的org.springframework.jndi.JndiObjectFactoryBean等缎玫。然后SessionFactory根據(jù)客戶的每次請(qǐng)求,將DataSource屬性設(shè)置成不同的數(shù)據(jù)源解滓,以到達(dá)切換數(shù)據(jù)源的目的赃磨。

Spring中用到的包裝器模式在類(lèi)名上有兩種表現(xiàn):一種是類(lèi)名中含有Wrapper,另一種是類(lèi)名中含有Decorator洼裤×诨裕基本上都是動(dòng)態(tài)地給一個(gè)對(duì)象添加一些額外的職責(zé)。


1.11腮鞍、觀察者模式(Observer)

應(yīng)用場(chǎng)景:定義對(duì)象間的一種一對(duì)多的依賴(lài)關(guān)系值骇,當(dāng)一個(gè)對(duì)象的狀態(tài)發(fā)生改變時(shí),所有依賴(lài)于它的對(duì)象

都得到通知并被自動(dòng)更新移国。

Spring中Observer模式常用的地方是Listener的實(shí)現(xiàn)吱瘩。如ApplicationListener。


各設(shè)計(jì)模式對(duì)比及編程思想總結(jié)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末迹缀,一起剝皮案震驚了整個(gè)濱河市使碾,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌祝懂,老刑警劉巖票摇,帶你破解...
    沈念sama閱讀 217,734評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異砚蓬,居然都是意外死亡矢门,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)祟剔,“玉大人傅事,你說(shuō)我怎么就攤上這事∠坷” “怎么了蹭越?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,133評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)教届。 經(jīng)常有香客問(wèn)我响鹃,道長(zhǎng),這世上最難降的妖魔是什么案训? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,532評(píng)論 1 293
  • 正文 為了忘掉前任买置,我火速辦了婚禮,結(jié)果婚禮上强霎,老公的妹妹穿的比我還像新娘忿项。我一直安慰自己,他們只是感情好城舞,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布轩触。 她就那樣靜靜地躺著,像睡著了一般家夺。 火紅的嫁衣襯著肌膚如雪脱柱。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,462評(píng)論 1 302
  • 那天拉馋,我揣著相機(jī)與錄音榨为,去河邊找鬼。 笑死煌茴,一個(gè)胖子當(dāng)著我的面吹牛随闺,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蔓腐,決...
    沈念sama閱讀 40,262評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼矩乐,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了合住?” 一聲冷哼從身側(cè)響起绰精,我...
    開(kāi)封第一講書(shū)人閱讀 39,153評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤撒璧,失蹤者是張志新(化名)和其女友劉穎透葛,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體卿樱,經(jīng)...
    沈念sama閱讀 45,587評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡僚害,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片萨蚕。...
    茶點(diǎn)故事閱讀 39,919評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡靶草,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出岳遥,到底是詐尸還是另有隱情奕翔,我是刑警寧澤,帶...
    沈念sama閱讀 35,635評(píng)論 5 345
  • 正文 年R本政府宣布浩蓉,位于F島的核電站派继,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏捻艳。R本人自食惡果不足惜驾窟,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望认轨。 院中可真熱鬧绅络,春花似錦、人聲如沸嘁字。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,855評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)纪蜒。三九已至假栓,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間霍掺,已是汗流浹背匾荆。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,983評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留杆烁,地道東北人牙丽。 一個(gè)月前我還...
    沈念sama閱讀 48,048評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像兔魂,于是被迫代替她去往敵國(guó)和親烤芦。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 前言 Spring Cloud Eureka是Spring Cloud Netflix微服務(wù)套件中的一部分析校,主要負(fù)...
    阿秀老師閱讀 280評(píng)論 0 0
  • 信任是人與人之間的橋梁智玻,而所有的橋梁連接起來(lái)的網(wǎng)絡(luò)稱(chēng)之為信聯(lián)網(wǎng)遂唧,一旦信聯(lián)網(wǎng)出現(xiàn)問(wèn)題,所有的一切交易或者合作都將面臨...
    山茶子閱讀 1,528評(píng)論 1 3
  • 夜深了吊奢,風(fēng)還沒(méi)有停下 紙皺了盖彭,筆還沒(méi)有躺下 驚蟄后的春夜 風(fēng)長(zhǎng)滿了思念 撿起一張紙,想將眷戀框限 只是,沒(méi)有了感情...
    君霏逸閱讀 299評(píng)論 2 0
  • 我的小孩召边,媽媽看到你每一天都在堅(jiān)持铺呵,雖然你偶爾也會(huì)犯犯懶,但是隧熙,媽媽不得不承認(rèn)其實(shí)你是個(gè)挺努力的孩子片挂,你在學(xué)習(xí)這條...
    嘿你好是我啊閱讀 271評(píng)論 0 6
  • 何為葉藝蘭?就是蘭草葉片上顯現(xiàn)出一定特征或變異的國(guó)蘭贞盯,通稱(chēng)為葉藝蘭宴卖,包括:線藝、斑藝邻悬、水晶藝和葉蝶藝等症昏。一般國(guó)蘭的...
    寒山草堂閱讀 1,372評(píng)論 0 0