設計模式無處不在,因為它就來自於我們的日常生活,提煉於生活經驗。
正握在你手中的手機,不能用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最新面試題