設計模式 | Spring中用到的設計模式,你知道幾個?

蔡大炮發表於2020-08-25

設計模式無處不在,因為它就來自於我們的日常生活,提煉於生活經驗。

正握在你手中的手機,不能用220V的電壓直接充電,需要一個專門的電源介面卡(充電器)才行。擺在你桌上的電腦也是一樣的,都需要“適配”。而 介面卡模式 (Adapter Pattern)正是由此總結而來。

從一個問題出發,為什麼Spring這麼牛

Spring 發展到今天,在Java開發中的地位毋庸置疑。人人都在用Spring,80%的開發者學完Java 就得學習Spring了。那Spring為啥這麼牛呢?其中肯定很大一部分原因就是因為Spring是一個把設計模式用的淋漓盡致的框架。從類名中就能體現出來。

設計模式 舉例
工廠模式 Factory BeanFactory
裝飾者模式 Wrapper BeanWrapper
代理模式 Proxy AopProxy
委派模式 Dispatcher DispatcherServlet
策略模式 Handler HandlerMapping
介面卡模式 Adapter HandlerAdpter
模板模式 Template JdbcTemplate
觀察者模式 Listener ContextLoaderListener

小夥伴們,趕緊開啟你的idea,使用上面的關鍵詞進行搜尋,將會獲得一個新的視角去審視我們的Spring原始碼了。前言就到這裡,那我們就正式進入今天的主題,設計模式


設計模式的由來

現在我們談論的設計模式,沒有特別說明的話,通常上就是指的1995年GoF(Gang of Four 四人組)所編寫的 Design Patterns: Elements of Reusable Object-Oriented Software 一書,該書包含了23種設計模式。 通常也被人稱為GoF 23。

在這裡大炮就不介紹全部了,網上一搜一大把,而且有些模式確實用的比較少。所以只列出常用的十種,也是比較重要的十種,大家看下,如果有不會的後面也會有專門的章節講到的。

型別 名稱 英文名
建立型 工廠模式 Factory Pattern
單例模式 Singleton Pattern
原型模式 Prototype Pattern
結構型 介面卡模式 Adapter Pattern
裝飾器 Decorator Pattern
代理模式 Proxy Pattern
行為型 策略模式 Strategy Pattern
模板模式 Template Pattern
委派模式(不屬於GoF 23) Delegate Pattern
觀察者模式 Observer Pattern

可能有些讀者注意到上面委派模式,並不屬於GoF 23。沒錯,設計模式並不侷限於GoF提出的,畢竟他們也是基於個人經驗總結出來的。如果哪天你突然腦中靈光一閃,通過自己的經驗也總結出來一個模式,並且能很好地解決一些問題,那也是完全合理OK的。


為什麼要使用設計模式

講了這麼多,為啥要用設計模式呢?我就是不用不行嘛?其實這兩個問題,仔細思索就會發現它完完全全就是個偽命題。我們每個人都是在“不得不“ 和 “不自覺”的使用設計模式。我們來看Mybatis中的一個例子:

file

SqlSession是一個介面,這裡定義了對資料庫的一大堆基本操作。我們對資料庫的操作都離不開它,這裡我們不看具體實現,只分析結構。它有三個實現類:

file

重點關注這個預設的DefaultSqlSession是怎麼建立的。我們還是隻分析結構。

file

可以看到,建立的步驟是很多的,入參就有三個,還呼叫了好幾個子方法,最終只是為了拿到DefaultSqlSession的例項,就是這句:

new DefaultSqlSession(configuration, executor, autoCommit);

試想,如果每個需要DefaultSqlSession的例項的呼叫者都需要寫這麼一大串,那得寫多少重複程式碼?萬一建立過程有改動,我們得改多少個地方?所以我們會很自然的想到把它抽到一個公共的地方,每次需要他,就去公共的地方拿就行了。即使有改動,也只需改動這個公共方法即可。平時我們的各種工具類,各種Util之類的,都是基於這個很直白,很自然的經驗。

其實針對這個openSessionFromDataSource(),就是一個非常標準的工廠模式的體現:工廠生產一個標準化的產品,大家需要這個產品都來我這裡拿就行了,並不需要關注其中的細節。而上面openSessionFromDataSource()方法,正是出自DefaultSqlSessionFactory,就是專門提供DefaultSqlSession例項的工廠。稍微看它一眼:

file

它過載了很多個openSession()方法,但最終都是呼叫openSessionFromDataSource()方法完成建立的。

從這個例子再次出發,我們嘗試猜下:它是從一開始的現場造輪子,然後到自然而然的使用設計模式,來感受下演變過程,首先是發現問題:

file

然後我們很自然的想到,把這些相同的邏輯、程式碼,放到一個公共方法裡頭,openSessionFromDataSource()方法應運而生,但是這個方法總得放一個地方吧,肯定不能是在各自的Service裡面,因為還是重複了嘛,所以很自然的新建一個類:

file

後面經過GoF的總結和提煉,它,Factory Pattern ,工廠模式就這麼出現了。其他設計模式的誕生和這個是一樣的,發現具有特徵的問題=>解決問題=>提煉特徵經驗=>形成設計模式

從這個過程我們可以體會到,是因為我們先去這麼做了,經過提煉和總結,才有設計模式的誕生。

綜上所述,不用設計模式也是可以正常實現我們需要的功能的。但是我們就是這麼自然而然地使用了,毫無違和感。從這也能得出一個結論,也應證了這篇文章的引言部分:設計模式來源於經驗(生活經驗、開發經驗)的總結。


總結

看了上面的例子,我們可以對設計模式做一些總結:

  • 設計模式是生活中經驗總結。
  • 不使用設計模式也能解決問題,但容易讓專案變成“屎山”,難以擴充套件和維護。使用設計模式能讓程式碼變得“優雅”,易於維護、易於擴充,並且節省時間(生命)。
  • GoF的釋出的設計模式一書形成了一種標準。出現了很多的關鍵字,比如Factory、Adapter,後人使用設計模式都會使用這些關鍵字來命名。Spring原始碼就是一個很好地例子,所以想看懂Spring原始碼,一定要學習設計模式

使用設計模式的準則:

不是為了用而強行使用設計模式,使用的過程應該是很自然的。誒,我需要用到這個模式才能很好的解決問題,所以我要用。

今天就到這裡了,祝大家七夕快樂,沒有物件的都能今晚脫單。下一篇就是單個設計模式的精講篇了,我們下期再見~

往期推薦

設計模式 | 4分鐘搞懂10種設計模式

蔡大炮準備正式開張啦

家雄又寫bug了

家雄別睡了,快起來改bug

原創不易,求個三連鼓勵下吧
微信搜尋 java-caidapao ,關注大炮~回覆“面試題”,領取2020最新面試題

相關文章