iT邦幫忙

2022 iThome 鐵人賽

DAY 9
1
自我挑戰組

【從工程師升級成為資深工程師的那檔事】 系列 第 9

【從工程師升級成為資深工程師的那檔事Day 9】設計模式 - 單例模式

  • 分享至 

  • xImage
  •  

這篇會開始分享創建型設計模式
創建型設計模式最主要的理念就是將物件(Object)的建立與使用分離,
藉由這樣的方式來提高系統的開發上的彈性。

常見的創建型設計模式有:

  • 單例模式 (Singletom Pattern)
  • 工廠模式 (Factory Pattern)
  • 生成器模式 (Builder Pattern)
  • 原型模式 (Prototype Pattern)

單例模式 Singleton Pattern

定義

保證一個類別(Class),在系統運行過程中只會被建立一個物件(Object)

結構

用途

單例模式的使用非常的廣泛,
像是連接資料庫的物件、
硬體設備的管理物件...等需要具有唯一性的物件(Object),
都可以使用單例模式。

單例模式除了確保物件(Object)的唯一性之外,
也能避免頻繁的創建與銷毀,達到節省系統資源的效果。

實作

單例模式的實作方式很多樣化,最常看到的設計方式有五種:

  • 貪婪單例 (Greed Singleton)
  • 延時初始化 (Lazy Initialization)
  • 雙鎖模式 (DCL,Double-Checked Locking)
  • 靜態內嵌類別 (Static Inner Class)
  • 枚舉單例 (Enum Singleton)

這邊分享兩個最常見的單例模式設計方式

延時初始化

public class SingletonClass{
  //宣告一個靜態的屬性
  private static SingletonClass instance;
  //將建構子設成private不讓外部使用
  private SingletonClass{
    //(省略內容)
  }
  public static SingletonClass getInstance(){
    if(instance == null){ 
      return new SingletonClass();
    }
    else {
      return instance;
    }
  
  }
  
}

這種設計方式能避免一開始就生成物件占用記憶體空間,第一次呼叫getInstance()才會創建物件。

靜態內嵌類別

public class SingletonClass{
  
  //將建構子設成private不讓外部使用
  private  SingletonClass{
    //(省略內容)
  }
  
  private static class SingletonInnerClass{
    //宣告一個靜態的屬性
    private SingletonClass instance = new SingletonClass();
  }
  
  public static SingletonClass getInstance(){
    return SingletonInnerClass.instance
  
  }
  
}

在外部類別(SingletonClass)載入的時候,內部類別(SingletonInnerClass)不會進行加載,
會一直到呼叫getInstance()的時候才會創建。
這種設計方式通過語言上的機制同時實現了延時加載、和執行緒安全的設計,
但這種設計方式是語言限定的設計方式,並不是所有語言都能使用這樣的設計。

結語

單例模式在專案上或多或少都有這樣的設計需求,
但是他卻是一種反模式(Anti-Pattern)的設計方式。
主要原因是因為getInstance()主要處理了內部的業務,
同時在其他method中又會需要負責外部的業務。
這會違反單一職責原則(SRP)。

其實這部分在網路上有很多的討論了,
所以在這就稍微說一下我的結論,
單例模式簡單好用,不影響架構,所以用就對了~


上一篇
【從工程師升級成為資深工程師的那檔事Day 8】淺談設計模式
下一篇
【從工程師升級成為資深工程師的那檔事 Day10】 設計模式 - 工廠模式
系列文
【從工程師升級成為資深工程師的那檔事】 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言