設計模式的簡單理解

參考鏈接:菜鳥教程-設計模式

什麼是設計模式?爲什麼要學設計模式?

設計模式 (Design Pattern) 代表了最佳的實踐,通常被有經驗的面向對象的軟件開發人員所採用。設計模式是軟件開發人員在軟件開發過程中面臨的一般問題的解決方案。這些解決方案是衆多軟件開發人員經過相當長的一段時間的試驗和錯誤總結出來的。
設計模式是一套被反覆使用的、多數人知曉的、經過分類編目的、代碼設計經驗的總結。使用設計模式是爲了重用代碼、讓代碼更容易被他人理解、保證代碼的可靠性。

小白理解: 我們平時所提及的設計包含很多種,如服裝設計、建築設計、模型設計等等。設計提供一種特定場景下的範式。如服裝設計師設計出不同款式的衣服,而不同款式的衣服適合於不同的場合。服裝設計師在設計衣服時,要考慮適用人羣和場合。建築設計師在對某一建築進行設計時,也必須考慮到這一建築的目的(如用於展覽、居住、會議等),還要考慮建築所在地的周圍環境(氣候、風水等)。軟件開發中設計模式則是提供一種面向特類問題的經驗模式或設計原則,以指導我們用更規範合理的方式去解決開發問題。

設計模式的類型

《設計模式》一書中共提到23種設計模式。這些模式可分爲三類:創建型模式、結構型模式、行爲型模式。

  • 創建型模式:主要用於創建對象。提供一種在創建對象的同時,隱藏創建邏輯的方式,而不是使用new運算符直接實例化對象。這使得程序在判斷針對某個給定實例需要創建哪些對象時更加靈活。
  • 結構型模式:主要用於處理類和對象的組合。
  • 行爲型模式:主要用於處理對象之間的通信,描述對類或對象怎樣進行交互和怎樣分配職責。

此外,根據範圍,即模式主要是用於處理類之間的關係還是處理對象之間的關係,可以分爲類模式和對象模式兩種。

小白理解: 小白現在看這些也記不住,大致瀏覽一下,等理解一些典型設計模式後再來回顧理解,每個設計模式屬於哪個類型。

設計模式的六大原則

注: 小白大致瀏覽,初步理解一下,看完一些設計模式後再來理解一遍

  1. 開閉原則(Open Close Principle)
  2. 里氏代換原則
  3. 依賴倒轉原則
  4. 接口隔離原則
  5. 迪米特法則,最少知道原則
  6. 合成複用原則

常用的設計模式

1. 適配器模式

適配器模式是作爲兩個不兼容的接口之間的橋樑,屬於結構型模式,它結合了兩個獨立接口的功能。

小白理解: 一個較好的例子,讀卡器是作爲內存卡和筆記本之間的適配器。將內存卡插入讀卡器,再將讀卡器插入筆記本,這樣可以通過筆記本來讀取內存卡。再比如,電源適配器,成功將220V電壓轉換成適合於電子設備的電壓和電流輸出。

2. 單例模式

屬於創建型模式,提供了一種創建對象的最佳方式。需要滿足以下特點:

  1. 單例類只能有一個實例
  2. 單例類必須自己創建自己的唯一實例
  3. 單例類必須給所有其他對象提供這一實例

意圖: 保證一個類僅有一個實例,並提供一個訪問它的全局訪問點
主要解決: 一個全局使用的類頻繁地創建與銷燬
優點:

  1. 在內存中只有一個實例,減少了內存的開銷,尤其是頻繁地創建和銷燬實例
  2. 避免對資源的多重佔用

實現
有多種實現方式,推薦使用雙重鎖,或靜態內部類方式

public class Singleton {
    private volatile static Singleton instance;
    private Singleton() {}
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                   instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

靜態內部類的方式

public class Singleton {  
    private static class SingletonHolder {  
        private static final Singleton INSTANCE = new Singleton();  
    }  
    private Singleton() {}  
    public static final Singleton getInstance() {  
        return SingletonHolder.INSTANCE;  
    }  
}

3. 建造者模式

使用多個簡單的對象一步一步地構建成一個複雜的對象,屬於創建型模式。
主要解決: 主要解決在軟件系統中,有時候面臨着“一個複雜對象”的創建工作,其通常由各個部分的子對象用一定的算法構成;由於需求的變化,這個複雜對象的各個部分通常面臨着劇烈的變化,但是將它們組合在一起的算法卻相對穩定。
應用實例: 1. 去肯德基,漢堡、可樂、薯條等是不變的,而其搭配的組合是經常變化的,從而生成各種不同的套餐; 2. Java中的StringBuilder類

4. 模板模式

一個抽象類公開定義了執行它的方法的方式。它的子類可以按需要重寫方法實現,但調用將以抽象類中定義的方式進行。屬於行爲型模式。
意圖: 定義一個方法的算法骨架,而將一些步驟延遲到子類中。模板方法使得子類可以不改變一個算法的結構即可重定義該算法的某些特定步驟
主要解決: 一些方法通用,卻在每個子類中都重寫了這些方法
如何解決: 將該方法分解,抽象出方法實現的共同結構,不同子結構由子類實現
使用場景: 1. 有多個子類共用的方法,且邏輯相同; 2. 重要的、複雜的方法,可以考慮作爲模板方法
注意: 爲防止惡意操作,模板方法一般加上final關鍵詞

實現
Game抽象類,play方法中提供了一套模板流程

public abstract class Game {
   abstract void initialize();
   abstract void startPlay();
   abstract void endPlay();
 
   //模板
   public final void play(){
 
      //初始化遊戲
      initialize();
 
      //開始遊戲
      startPlay();
 
      //結束遊戲
      endPlay();
   }
}

各個子類中實現模板方法中的子步驟即可

public class Cricket extends Game {
 
   @Override
   void endPlay() {
      System.out.println("Cricket Game Finished!");
   }
 
   @Override
   void initialize() {
      System.out.println("Cricket Game Initialized! Start playing.");
   }
 
   @Override
   void startPlay() {
      System.out.println("Cricket Game Started. Enjoy the game!");
   }
}
public class Football extends Game {
 
   @Override
   void endPlay() {
      System.out.println("Football Game Finished!");
   }
 
   @Override
   void initialize() {
      System.out.println("Football Game Initialized! Start playing.");
   }
 
   @Override
   void startPlay() {
      System.out.println("Football Game Started. Enjoy the game!");
   }
}

5. 外觀模式

外觀模式隱藏系統的複雜性,並向客戶端提供了一個客戶端可以訪問系統的接口,屬於結構型模式。
涉及到一個單一的類,該類提供了客戶端請求的簡化方法和對現有系統類方法的委託調用。


未完待續

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章