什麼是設計模式
設計模式( Design Pattern )代表了最佳的實踐,通常被有經驗的面向對象的軟體開發人員所采用。設計模式是軟體開發人員在軟體開發過程中面臨的一般問題的解決方案。這些解決方案是衆多軟體開發人員經過相當長一段時間的試驗和錯誤總結出來的。
上面的解釋來自于網絡,是比較标準的定義,可以從中篩選出幾個關鍵字來幫助我們了解什麼是設計模式:
- 最佳實踐
- 解決方案
- 試驗和錯誤總結
從上面的三個關鍵詞中可以總結出,設計模式就是在針對編碼過程中遇到的問題總結出來的最佳解決方案。
那麼這些問題指的是什麼問題呢?面向對象的程式應該具有可維護性、代碼可複用性、擴充性及靈活性,要解決的問題就是代碼可維護性問題、複用性問題、擴充性問題及靈活性問題。
簡單來說,設計模式就是指導你如何寫出可維護、可複用、可擴充及靈活的代碼。
設計模式分類
設計模式總共有 23 種,總體來說可以分為三大類:建立型模式( Creational Patterns )、結構型模式( Structural Patterns )和行為型模式( Behavioral Patterns )。
分類 | 關注點 | 包含 |
建立型模式 | 關注于對象的建立,同時隐藏建立邏輯 | 工廠模式、抽象工廠模式、單例模式、建造者模式、原型模式 |
結構型模式 | 關注類和對象之間的組合 | 擴充卡模式、過濾器模式、裝飾模式、享元模式、代理模式、外觀模式、組合模式、橋接模式 |
行為型模式 | 關注對象之間的通信 | 責任鍊模式、指令模式、中介者模式、觀察者模式、狀态模式、政策模式、模闆模式、空對象模式、備忘錄模式、疊代器模式、解釋器模式、通路者模式 |
上面的三種分類說明,有助于在開發時思考目前場景應該使用哪種分類。大家不一定要全部記住,有個大概的了解即可。
學習設計模式
1. 為什麼要學設計模式
寫出可維護、可複用、可擴充及靈活的代碼是我們的目的,也是學習設計模式的理由,但是這個理由對我們來說太抽象,下面從 “ 讀 ” 和 “ 寫 ” 兩方面來說明到底為什麼要學習設計模式。
- 讀
作為開發人員,不可避免地要接觸其他人寫的代碼,有的是一些知名的庫或架構,例如 Spring 、Shiro 等。但是當我們去閱讀這些架構源碼的時候會發現無從下手,因為類太多了,關系太複雜,而且很多類的命名看不懂,比如 xxxBuilder 、xxxStrategy 、xxxFilter 等,一個詞看不懂就可能導緻你直接放棄繼續閱讀。
如果沒有學過設計模式,自然看不懂,學習設計模式可以有效地幫助你閱讀代碼,即便不能百分百幫到你,至少也能幫到百分之三四十。
- 寫
每一個開發人員必然噴過其他人寫的代碼,覺得其他人的代碼有的寫得很垃圾,尤其是要擴充功能或者修改功能的時候,恨不得全部删掉重新寫,其實在其他人看來你的代碼也是如此。是以寫出一手讓人無話可說的代碼是很有必要的,不僅可以滿足你的小小成就感,也可以讓你的程式更快速穩定地發展。
在一個項目組中,如果大家都學習過設計模式,那麼當你閱讀或修改同僚寫的代碼時也将得心應手,少了很多麻煩。
2. 如何學好設計模式
如今網上和書上都有大量的設計模式教程,但是他們大部分都有一個共同點:僅僅使用生活中的例子。
比如前幾年我第一次學習設計模式,在學到擴充卡模式時,教程中抛出了一個電器的插頭問題:
你家插座隻有三頭的,但電器插頭是兩頭的,怎麼辦?弄個插頭擴充卡将兩頭轉換成三頭。
Nice,這個例子簡單明了,作為新手的我瞬間明白了擴充卡的含義,就是在不相容的雙方中間做一層轉化。但是後來發現在實際編碼中根本用不上這個設計模式,因為我不會用。
生活中的例子的确可以幫助我們了解設計模式,這是毋庸置疑的,但是想要真正用好設計模式,實際項目中的案例是必不可少的,這也是我寫這個專欄的原因,希望通過分析實際案例,能夠幫到更多想要學習設計模式的同行。
下面給出幾點更加具體的建議:
- 從生活例子中去了解設計模式;
- 從實際案例去了解設計模式的使用場景;
- 動手實踐,在學完實際案例之後,不妨動手寫一寫,不要寫生活中的例子,自己構造一個小功能,用上你的設計模式;
- 改變自己的意識,在開發或修改一個功能時,首先要下意識地去思考這個功能将來在修改和擴充上會遇到什麼問題,能否用上設計模式。記住一定要思考、一定要思考、一定要思考,即便最終用不上,也能讓你回顧一遍設計模式的内容,使其知識更牢固。很多開發者不是不會用,而是根本沒有想過要用設計模式,久而久之這方面的能力自然就弱化了。
專欄說明
1. 專欄内容
本專欄每一篇文章都包含三大部分:
- 解釋和了解設計模式;
- 至少介紹一個實際案例( 實際案例有些是我自己寫的,有些來自于已有的架構或庫 );
- 設計模式優缺點。
2. 必要準備
本專欄将使用 Java 語言講解設計模式,雖然設計模式與語言本身無關,但是本專欄中有許多實際案例都是來自于知名的 Java 架構源碼,如果沒有 Java 基礎,學習效果可能不佳。
除了要求 Java 基礎之外,還需要了解 UML 圖,如果不了解 UML,隻需要知道以下幾種 UML 關系即可:
- 泛化,可以簡單地了解為繼承關系;
- 實作,一般是接口和實作類之間的關系;
- 關聯,一種擁有關系,比如老師類中有學生清單,那麼老師類和學生類就是擁有關系;
- 聚合,整體與部分的關系,但是整體和部分是可以分離而獨立存在的,如汽車類和輪胎類;
- 組合,整體與部分的關系,但是二者不可分離,分離了就沒有意義了,例如,公司類和部門類,沒有公司就沒有部門;
- 依賴,一種使用關系,例如建立 A 類必須要有 B 類。