前言
《設計模式自習室》系列,顧名思義,本系列文章帶你溫習常見的設計模式。
但是,在開篇中,我想要先整體的介紹下設計模式,讓大家知道為什么要學習設計模式。
所以這篇文章的主要內容是:
- 我對設計模式的理解
- 設計模式的至高目標:解耦(高內聚低耦合)
- 設計模式的分類
- 設計模式遵循的設計原則
- 為什么我寫代碼常常用不到設計模式?
文章會逐步更新于我的各個博客上(見文章尾部介紹),也希望各位觀眾老爺能夠關注我的個人公眾號:后端技術漫談,所有文章都會在上面發布,不會錯過精彩好看的文章。
為什么我們需要設計模式?
我對設計模式的理解
當我剛剛接觸程序,最初聽到“設計模式”這四個字的時候,我常常會思考一個問題,這個東西為什么這么拗口。就像我當初聽到“離散數學”,“具體數學”一樣,有種摸不著頭腦的感覺。
帶著這種疑問,我嘗試看了幾篇介紹設計模式的文章,它們都對設計模式進行了這樣的介紹:
軟件設計模式(Design pattern),又稱設計模式,是一套被反復使用、多數人知曉的、經過分類編目的、代碼設計經驗的總結。 使用設計模式是為了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性、程序的重用性。
看完之后,我更加摸不著頭腦了。看著什么單例模式,責任鏈模式的代碼,感覺老師從來就沒提過這些,為什么要把代碼寫成這樣,好好的寫完自己想要的功能不就好了嘛???
是的,設計模式,對于入門程序員來說,確實有點空中樓閣,尤其是對于沒接觸過大型項目的人而言,這些代碼是如此的陌生,甚至有點“故弄玄虛”。
但是,生活往往就是有這么多“但是”!當你逐漸入門了程序編寫,接觸到了大型的,功能復雜的,需要多人合作的代碼后,再回頭看設計模式,往往就有了越來越清晰的認識。
隨著我的經驗積累,再回來復習設計模式,常常有醒悟的感覺。接下來就說說我對設計模式的認知:
設計模式的英文是什么?Design pattern,這是一個非常之準確的詞匯,個人認為比中文翻譯好太多了。
Patten中文釋義:. n. 模式;圖案;樣品. vt. 模仿
pattern往往意味著是一種既定的準則,從它的動詞可以看到,他有模仿的意思,也就是說,這樣的代碼設計,是一系列前人留下的經驗,只要跟著這樣寫代碼,往往能夠讓你的代碼,更加簡潔,更加健壯,更加優雅!
我覺得他應該有個意譯的名字,叫做:代碼設計的最佳實踐!
是不是很耳熟,還記得最近很火的《阿里巴巴JAVA開發手冊》,以及經典的《Effective Java》嗎?他們都是屬于經驗總結型的知識,目的是幫助程序員寫出更優雅的代碼!
如果你沒聽過上面的幾本書,沒關系,當然,你也可以看看我之前的文章 《阿里巴巴Java開發手冊》閱讀筆記,大概了解下他們的內容是什么樣的,你就會理解我說的“他們是一個類型的”。
高內聚低耦合
設計模式是一種代碼設計思路,其最最本質的目的是為了解耦,延伸一點的話,還有為了可擴展性和健壯性,但是這都是建立在解耦的基礎之上。
有同學要問了,“解耦”是什么意思呢?請先看下面兩個概念:
高內聚
系統中A、B兩個模塊進行交互,如果修改了A模塊,不影響模塊B的工作,那么認為A是高度內聚的。
低耦合
那么當B發生改變時,A模塊仍然可以正常工作,那么就認為A與B是低耦合的。
所以解耦,本質上就是讓不同的代碼塊各司其職,互不干擾!
設計模式的分類
創建型模式
創建型模式將創建對象的過程進行了抽象,也可以理解為將創建對象的過程進行了封裝,作為客戶程序僅僅需要去使用對象,而不再關系創建對象過程中的邏輯。
- 簡單工廠模式(Simple Factory):簡單工廠模式不是GoF總結出來的23種設計模式之一
- 工廠方法模式(Factory Method)
- 抽象工廠模式(Abstract Factory)
- 創建者模式(Builder)
- 原型模式(Prototype)
- 單例模式(Singleton)
結構型模式
結構型模式是為解決怎樣組裝現有的類,設計它們的交互方式。例如:擴展性(外觀、組成、代理、裝飾)、封裝(適配器、橋接)。因為如何設計對象的結構、繼承和依賴關系會影響到后續程序的維護性、代碼的健壯性、耦合性等。
- 外觀模式/門面模式(Facade門面模式)
- 適配器模式(Adapter)
- 代理模式(Proxy)
- 裝飾模式(Decorator)
- 橋梁模式/橋接模式(Bridge)
- 組合模式(Composite)
- 享元模式(Flyweight)
行為型模式
行為模式刻劃了在程序運行時難以跟蹤的復雜的控制流,進一步可分為行為類模式和行為對象模式。
行為類模式使用繼承機制在類間分派行為。
行為對象模式使用對象聚合來分配行為。一些行為對象模式描述了一組對等的對象怎樣相互協作以完成其中任何一個對象都無法單獨完成的任務。
- 模板方法模式(Template Method)
- 觀察者模式(Observer)
- 狀態模式(State)
- 策略模式(Strategy)
- 職責鏈模式(Chain of Responsibility)
- 命令模式(Command)
- 訪問者模式(Visitor)
- 調停者模式(Mediator)
- 備忘錄模式(Memento)
- 迭代器模式(Iterator)
- 解釋器模式(Interpreter)
三者之間的區別和聯系
創建型模式提供生存環境,結構型模式提供生存理由,行為型模式提供如何生存。
創建型模式為其他兩種模式使用提供了環境。
結構型模式側重于接口的使用,它做的一切工作都是對象或是類之間的交互,提供一個門。
行為型模式顧名思義,側重于具體行為,所以概念中才會出現職責分配和算法通信等內容。
設計原則
設計模式是優雅的代碼實現,所以會講究標準的設計原則,常用的設計原則如下:
- 開閉原則: 對擴展開放,對修改關閉
- 里氏轉換原則: 子類繼承父類,單獨完全可以運行
- 依賴倒轉原則: 引用一個對象,如果這個對象有底層類型,直接引用底層類型
- 接口隔離原則: 每一個接口應該是一種角色
- 合成/聚合復用原則: 新的對象應使用一些已有的對象,使之成為新對象的一部分
- 迪米特原則: 一個對象應對其他對象有盡可能少的了解
為什么我寫代碼常常用不到設計模式?
這一點,是我臨時加上的,因為我之前也有這樣的困惑。看了這么多設計模式,為什么我日常使用中根本就不會想到去用呢?我想給出幾點回答:
第一,我們日常開發中,經常是使用框架在構造大型的項目,框架已經為我們考慮到了太多的設計,已經讓我們開箱即用。所以我們常常只需要CRUD(增刪改查)。其實框架的源碼中,使用到了非常多的設計模式,這也是為什么很多大牛在推薦我們看某某框架的源碼前,常常建議我們先看設計模式。否則看源碼的時候,會非常的吃力,因為不知道為什么會這樣寫代碼
第二,設計模式的使用往往在你的編程經驗積累到一定程度后,在遇到了大量的問題后,你會想著去進行合理的代碼結構設計來解決一些常常會遇到的問題,這時候,你就會慢慢的想到使用設計模式了!所以不要急,你可以先不用強行往自己的項目上放設計模式,但一定要先了解各種設計模式
第三,如果你急著想要上手實踐設計模式,那么,做一個完全不依賴大型框架的項目吧,可以是一個工具類,可以是一個小功能腳本,只要不依賴那些復雜的框架,很快你就能發現你代碼中可以應用設計模式的地方,別問我怎么知道的,快去自己造一個輪子吧!