天天看點

寂然解讀設計模式 - 設計模式伊始

I walk very slowly, but I never walk backwards            

大家好~,我是寂然,本教程我們來學習設計模式,其實設計模式,好多人稱之為 " Java設計模式 ",但其實設計模式并不是 Java 的專利,它不依賴語言,同樣适用于 C++、C#、JavaScript 等其它面向對象的程式設計語言,這是首先要和大家明确的一點,Java 是典型的面向對象的程式設計語言,是以本教程以 Java 為基礎來講解設計模式

内容介紹

凡事預則立,不預則廢,再開始學習一門新的課程之間,我們首先要來明确一下學習的内容及路線,首先,在正式的内容開始之前,我們首先要明确以下兩點

  • 為什麼要學習設計模式,以及設計模式的重要性
  • 設計模式的産生背景以及概念

    然後會依次給大家介紹設計模式七大設計原則,認識UML類圖以及類圖六大關系,設計模式的分類以及二十三種設計模式全面解析,當然,不是蜻蜓點水哈,本教程中的每一個設計模式,我會給大家采用如下路線進行全面介紹

舉例應用場景 -> 設計模式介紹 -> 分析實作步驟 -> 代碼案例實操 -> 架構或項目中用到該模式的源碼分析

最後,希望大家通過本系列的學習,掌握多種設計模式的實作和本質,能夠在工作中靈活運用解決實際問題,寫出優雅并且維護性可讀性高的代碼,那我們開始啟程吧

為什麼要學設計模式

其實類似大家這樣有一定工作經驗的開發人員,了解以及進一步掌握設計模式是非常有必要的,因為平時大家接到開發任務,首要目标是實作功能,而且現在的節奏~,時間緊,任務重,大家沒有,可能也來不及做其他的考慮,是以,大部分程式員寫的代碼,其實可維護性,可讀性都很差,類之間的關系非常複雜,沒有條理,那例如以後要增加新的需求,現有的程式如何進行變動成本最低?如何保證新的功能子產品不會對原來的項目産生影響?

案例引入

舉個栗子,大家看下如下兩張圖

寂然解讀設計模式 - 設計模式伊始

茅草小屋大家應該都看到過,一個簡單的架構,蓋幾捆茅草,他不需要什麼設計,也不需要花時間合理去架構,設計他的初衷是為了遮風擋雨,大家可類比于單一的應用架構,個人開發,一個應用就能将所有的功能部署在一起,打個war包扔到tomcat裡即可運作,由于模型簡單,代碼層面也不需要考慮太多,重點在于功能的實作

寂然解讀設計模式 - 設計模式伊始

那大家來看圖二的摩天大廈,一座這樣的建築,可以直接開工嘛?顯示是不可以的,在項目開始之前,設計師需要畫設計圖紙,考慮大廈的采光,通風,安全通道,承重...,做大量的準備工作

同樣,大家可以類比于現在的分布式微服務項目,随着項目的複雜度直線上升,在項目開始之前,要進行需求宣講,架構設計評審...,這樣的項目都是團隊合作,除了要考慮服務之間的互動,服務内部代碼的可讀性,可靠性,可維護性都是我們需要重點考慮的,這時候,設計模式就顯得尤為重要

設計模式可以讓你知道在某些場景下如何來設計出适合場景的架構,通俗點說,可以讓你的代碼更加“優雅”
設計模式的重要性

當然,設計模式,大家可以通俗了解為是前輩程式員在大量開發中累積的經驗,掉了大量的頭發,然後歸納為了這些設計模式,當然,設計模式絕不是代表了絕對的開發真理,在問題面前應該靈活變通,當你的代碼類結構合理, 易于維護 ,可擴充性強,那麼設計模式的目的就已經達到了,切記不要過渡的使用設計模式,為了用而用

當然,上面的說法還是針對于大牛而言的,對于咱們這種幾年經驗的碼農,掌握設計模式就很有必要,當大家學習并且使用到設計模式,如果你的項目做的非常大,之間關系非常複雜的時候,仍然能讓你能掌控這些代碼,不會出現代碼失控的情況,如同上面的案例,設計模式就是設計大廈的圖紙

其次,很多成熟架構的源碼裡大量的用到了設計模式,如果掌握設計模式,對于閱讀源碼會有很大的幫助,如果你要學習源碼,那麼學習完設計模式再看的話,會更加清晰

設計模式的背景

設計模式最早出現在建築領域,是克裡斯托弗.亞曆山大(Christopher Alexander,頭銜很多的大佬) 對環境中不斷出現的問題, 總結出這些問題的解決方案。以後再遇到這些問題時,可以重用這些方案來解決

四人幫(GOF)

1994年,有四位作者:Erich Gamma,Richard Helm,Ralph Johnson和John Vlissides發表了一本題為《設計模式 - 可重用的面向對象軟體元素》的圖書,該書在軟體開發中開創了設計模式的概念,第一次将設計模式提升到理論高度,并将之規範化,這些作者被統稱為四人幫(GOF),如下就是這四個大佬~

寂然解讀設計模式 - 設計模式伊始

設計模式的概念

其實,關于設計模式的概念,上面已經作出解釋,當然,我們來看下設計模式的官方概念

設計模式(design pattern)是對軟體設計中普遍存在(反複出現)的各種問題,所提出的解決方案

這個術語是由埃裡希·伽瑪(Erich Gamma)等人在 1990 年代從建築設計領域引入到計算機科學的

設計模式的原則

上面提到了,我們為什麼要學習設計模式,在這裡做一個簡單的總結

設計模式是為了讓軟體(程式)具有更好的代碼重用性,可讀性,可擴充性,可靠性

理論聽着雲裡霧裡,那到底是什麼意思呢?舉個栗子,何為具有更好的可靠性呢?

  • 代碼重用性:即相同功能的代碼,不需要多次編寫,可以重複使用
  • 可讀性:即編碼的規範性,便于其他程式員閱讀和了解
  • 可擴充性:即當需要增加新功能時,成本低,也稱為可維護性
  • 可靠性:即代碼強壯,當增加新的功能時,對原有的功能沒有影響

其實說到底,就是讓程式呈現出高内聚,低耦合的特性

高内聚&低耦合

耦合主要描述子產品之間的關系,内聚主要描述子產品内部,當然子產品的粒度可大可小(小到一個類 大-到一個系統)

  • 高内聚 一個功能子產品内部的元素,關聯越強,則内聚越高,子產品的單一性更強,一個子產品應當盡可能獨立完成某個功能
  • 低耦合 功能子產品和功能子產品之間耦合性很低,A子產品出現問題,避免影響B子產品,比如子產品A直接操作了子產品B中資料, 則視為強耦合,例如下圖,我們假設這樣一個場景,發貨系統發貨,寫入消息隊列,訂單系統這邊訂閱消息隊列裡的消息,如果訂單系統出現故障,不影響發貨系統正常寫入消息隊列,利用了消息中間件,兩個系統之間的耦合性大大降低
寂然解讀設計模式 - 設計模式伊始
設計模式原則引出

了解了高内聚&低耦合之後,我們正式進入到設計模式七大原則,那麼,何為設計模式的原則呢?

其實是程式員在程式設計時,應當遵守的原則,也是各種設計模式的基礎 (即:設計模式為什麼 這樣設計的依據)

是以,我們先來認識一下設計模式常用的七大原則:

單一職責原則、接口隔離原則、依賴倒置原則、裡氏替換原則、開閉原則、迪米特法則、合成複用原則

這些原則并不是孤立存在的,它們互相依賴,互相補充,下面表格對于七大原則進行了一個簡單的介紹

名稱 設計原則簡介 重要性
單一職責原則 類的職責要單一,不能将太多的職責放在一個類中 ★★★★☆
開閉原則 軟體實體對擴充是開放的,但對修改是關閉的,即在不修改一個軟體實體的基礎上去擴充其功能 ★★★★★
裡氏代換原則 在軟體系統中,一個可以接受基類對象的地方必然可以接受一個子類對象
依賴倒置原則 要針對抽象層程式設計,而不要針對具體類程式設計
接口隔離原則 使用多個專門的接口來取代一個統一的接口 ★★☆☆☆
合成複用原則 在系統中應該盡量多使用組合和聚合關聯關系,盡量少使用甚至不使用繼承關系
迪米特法則 一個軟體實體對其他實體的引用越少越好,或者說如果兩個類不必彼此直接通信,那麼這兩個類就不應當發生直接的互相作用,而是通過引入一個第三者發生間接互動 ★★★☆☆

設計原則和設計模式也是對系統進行合理重構的指南針,那麼,何為合理重構?

合理重構,是在不改變軟體現有功能的基礎上,通過調整程式代碼改善軟體的品質、性能,使其程式的設計模式和架構更趨合理,提高軟體的擴充性和維護性

下期預告

下一節,我們正式進入設計模式的學習,我會為大家用多個案例分析,來解讀設計模式原則之單一職責原則,以及它的注意事項和細節,從設計模式的原則開始,一步步走進設計模式的大門,最後,希望大家在學習的過程中能夠感覺到設計模式的有趣之處,高效而愉快的學習,下期見~