設計模式無處不在,因為它就來自於我們的日常生活,提煉於生活經驗。
正握在你手中的手機,不能用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中的一個例子:
SqlSession是一個介面,這裡定義了對資料庫的一大堆基本操作。我們對資料庫的操作都離不開它,這裡我們不看具體實現,只分析結構。它有三個實現類:
重點關注這個預設的DefaultSqlSession是怎麼建立的。我們還是隻分析結構。
可以看到,建立的步驟是很多的,入參就有三個,還呼叫了好幾個子方法,最終只是為了拿到DefaultSqlSession的例項,就是這句:
new DefaultSqlSession(configuration, executor, autoCommit);
試想,如果每個需要DefaultSqlSession的例項的呼叫者都需要寫這麼一大串,那得寫多少重複程式碼?萬一建立過程有改動,我們得改多少個地方?所以我們會很自然的想到把它抽到一個公共的地方,每次需要他,就去公共的地方拿就行了。即使有改動,也只需改動這個公共方法即可。平時我們的各種工具類,各種Util之類的,都是基於這個很直白,很自然的經驗。
其實針對這個openSessionFromDataSource(),就是一個非常標準的工廠模式的體現:工廠生產一個標準化的產品,大家需要這個產品都來我這裡拿就行了,並不需要關注其中的細節。而上面openSessionFromDataSource()方法,正是出自DefaultSqlSessionFactory,就是專門提供DefaultSqlSession例項的工廠。稍微看它一眼:
它過載了很多個openSession()方法,但最終都是呼叫openSessionFromDataSource()方法完成建立的。
從這個例子再次出發,我們嘗試猜下:它是從一開始的現場造輪子,然後到自然而然的使用設計模式,來感受下演變過程,首先是發現問題:
然後我們很自然的想到,把這些相同的邏輯、程式碼,放到一個公共方法裡頭,openSessionFromDataSource()方法應運而生,但是這個方法總得放一個地方吧,肯定不能是在各自的Service裡面,因為還是重複了嘛,所以很自然的新建一個類:
後面經過GoF的總結和提煉,它,Factory Pattern ,工廠模式就這麼出現了。其他設計模式的誕生和這個是一樣的,發現具有特徵的問題=>解決問題=>提煉特徵經驗=>形成設計模式。
從這個過程我們可以體會到,是因為我們先去這麼做了,經過提煉和總結,才有設計模式的誕生。
綜上所述,不用設計模式也是可以正常實現我們需要的功能的。但是我們就是這麼自然而然地使用了,毫無違和感。從這也能得出一個結論,也應證了這篇文章的引言部分:設計模式來源於經驗(生活經驗、開發經驗)的總結。
總結
看了上面的例子,我們可以對設計模式做一些總結:
- 設計模式是生活中經驗總結。
- 不使用設計模式也能解決問題,但容易讓專案變成“屎山”,難以擴充套件和維護。使用設計模式能讓程式碼變得“優雅”,易於維護、易於擴充,並且節省時間(生命)。
- GoF的釋出的設計模式一書形成了一種標準。出現了很多的關鍵字,比如Factory、Adapter,後人使用設計模式都會使用這些關鍵字來命名。Spring原始碼就是一個很好地例子,所以想看懂Spring原始碼,一定要學習設計模式。
使用設計模式的準則:
不是為了用而強行使用設計模式,使用的過程應該是很自然的。誒,我需要用到這個模式才能很好的解決問題,所以我要用。
今天就到這裡了,祝大家七夕快樂,沒有物件的都能今晚脫單。下一篇就是單個設計模式的精講篇了,我們下期再見~
往期推薦
原創不易,求個三連鼓勵下吧
微信搜尋 java-caidapao ,關注大炮~回覆“面試題”,領取2020最新面試題