Thinkin Markdown

Singleton 單例模式

單純但暗藏危機

發佈時間 2020-03-24
閱讀時間 4 分鐘
主題 設計模式
標籤
創建型模式

此篇文章簡單帶大家了解 Singleton 單例模式 哦,有興趣就往下看吧!

目的

以下擷取自 wikipedia

The singleton pattern is a software design pattern that restricts the instantiation of a class to one “single” instance.

單例模式是軟體設計原則之一,其目的在於將類別實例化限制為一”單個”實例。

❗️ 換句話說,從應用程式開始生命週期所創造的這一”單個”實例,理論上到應用程式結束其生命週期都只會存在一個。

類別圖

singleton

從類別圖看有幾點需注意:

  1. instance 為靜態變數
  2. Singleton 類別建構子為 private(不讓其它類別有機會創造實例)
  3. getInstance 為靜態方法

程式碼

class Singleton {

    private static instance: Singleton;

    private constructor() { }

    /**
     * 取得實例
     * @returns Singleton
     */
    public static getInstance(): Singleton {

        if(!Singleton.instance)
            Singleton.instance = new Singleton();

        return Singleton.instance;
    }
}

詳細可參考範例程式碼···

好處

  1. 從應用程式生命週期開始至結束,應保證只能取到一個且相同的實例(物件)
  2. 因第 1 點關係,故可減少創造實例的開銷(記憶體浪費)
  3. 與全域變數不同的是該模式可以延遲實例初始化(Lazy initialization),但在部分程式語言實作該模式時,仍要注意是否有同步(Synchronize)問題發生

壞處

  1. 程式碼在無形之中有了隱藏性的依賴關係(因為不是透過介面暴露而得知
  2. 若單純僅使用該模式,它算是打破了 SRP(Singleton 類別包含了創建目標類別實例的職責目標類別實例原有的行為執行職責),但可以透過工廠(Factory)來分離出創建實例的職責
  3. 因第 1 點關係,故會導致類別之間緊密耦合(Tight coupling)
  4. 因第 3 點關係,單元測試會變得較為困難,因單元測試比較大的前提會是類別之間需鬆耦合(Loose coupling),從而可以獨立對它們進行單元測試
  5. 由於保證只能取到一個且相同的實例,所以在多執行緒(Multi-threading)下,需要特別注意狀態變化,若要最小程度的影響應用程式,則該實例執行途中變動幅度應該要最小
  6. 因第 5 點關係,一但取出之實例對於商業邏輯有極大程度影響時,則每一次商業邏輯的結果不一定會如預期,間接導致單元測試很難撰寫(因為沒有可以預期的案例)
  7. 一般來說透過靜態方法來初始化實例是比較好的方式,但靜態方法會導致開發人員知道他們不需要知道的類別內部程式碼結構
  8. 因第 7 點關係,若有寫過單元測試就會知道,即便使用一些單元測試框架,也非常不好處理靜態方法···
  9. 要擴展該模式並非易事(若以全面性來考量,則會考慮太多狀況),可能可以透過裝飾者模式(Decorator Pattern)在不影響現階段行為下,附加新行為於物件上
  10. 若以某些語言(原生或非原生)GC 回收機制來看,該模式可能會有較為棘手的記憶體管理問題出現

結論

其實該模式早前就於 GoF《Design Patterns: Elements of Reusable Object-Oriented Software》中出現,但其實到目前為止,還沒有一個完全的定調認為該模式屬於反模式(Anti-pattern),所以網路上有蠻多人議論紛紛,到底該模式是不是一個反模式!?

總結來說,使用 Singleton 模式需要非常小心且最好經過深思熟慮,至於它是不是反模式,則端看開發人員當初的考量及如何去設計類別···

如果是我的話,我會先考慮什麼情況會需要使用單例模式,有沒有其它的替代方案可以先處理!?因為在怎麼樣我都想避掉使用靜態變數或方法,因為一但使用了靜態變數或方法,接著你開始就要考慮如何撰寫單元測試了···😱

參考

💭 What Is a Singleton?

💭 What is so bad about singletons? [closed]

💭 When Singleton Becomes an Anti-Pattern

如果這篇文章對你有幫助,歡迎分享給更多人!

贊助支持

如果你喜歡我們的文章,或是這些內容對你有幫助,歡迎透過以下平台請我們喝杯咖啡,支持我們持續創作!

Ko-fi

作者

NE

Neil Tsai

樂於分享所見所聞所覺所知的全端工程師

留言功能需要 Cookie 授權

為了載入留言功能,我們需要您同意使用「功能性 Cookie」。您可以隨時在設定中調整。

免責聲明

本網站對於任何使用或引用本網站網頁資料引致之損失或損害,概不負責。本網站亦有權隨時刪除、暫停或編輯本網站所登載之各項資料,以維護本網站之權益。除法律有強制規定外,在任何情況下,本網站對於 (1) 使用或無法使用本網站之各項服務;(2) 經由本網站取得訊息或進行交易;(3) 第三人在本網站上之陳述或作為;以及 (4) 其他與本網站服務有關之事項所致生之任何直接、間接、附帶、特別、懲罰性或衍生性損害,一概不負賠償責任。

CopyRight © 2026 Thinkin Markdown