單件模式

来源:http://www.cnblogs.com/zwt-blog/archive/2017/03/25/6617373.html
-Advertisement-
Play Games

一、基本概述 單件模式:確保一個類只有一個實例,並提供一個全局訪問點。 解析如下: 1)首先,該Singleton的構造函數必須是私有的,以保證客戶程式不會通過new()操作產生一個實例,達到實現單例的目的; 2)因為靜態變數的生命周期跟整個應用程式的生命周期是一樣的,所以可以定義一個私有的靜態全局 ...


 一、基本概述

單件模式:確保一個類只有一個實例,並提供一個全局訪問點。

解析如下:

  1)首先,該Singleton的構造函數必須是私有的,以保證客戶程式不會通過new()操作產生一個實例,達到實現單例的目的;

  2)因為靜態變數的生命周期跟整個應用程式的生命周期是一樣的,所以可以定義一個私有的靜態全局變數uniqueInstance來保存該類的唯一實例;

  3)必須提供一個全局函數訪問獲得該實例。

如下圖結構說明圖:

 

二、詳細說明

單件模式的創建,有三種方式。

  1. 使用經典方式,存在一個問題,當有多個線程同時訪問時,會創建多個實例,違反了單件的本意。
  2. 使用急切方式,如果應用程式總是創建並使用單件實例,或者在創建和運行時方面的負擔不太繁重,該方式可以使用。它的初始化交由靜態構造函數實現,並可以在運行時編譯。在這種模式下,無需自己解決線程安全性問題,CLR會給我們解決。由此可以看到這個類被載入時,會自動實例化這個類,而不用在第一次調用GetInstance()後才實例化出唯一的單例對象。
  3. 使用懶惰(雙重檢查加鎖)方式,首先檢查是否實例已經創建,如果尚未創建,“才”進行同步。這樣一來,只有第一次會同步,同步中會再檢查是否實例已經創建。如果性能是你關心的重點,那麼這個做法可以幫你大大地減少GetInstance()的時間耗費。

問:難道我不能創建一個類,把所有的方法和變數都定義為靜態的,把類直接當作一個單件?

答:如果你的類自給自足,而且不依賴於複雜的初始化,那麼你可以這麼做。但是,因為靜態初始化的控制權是在CLR手上,這麼做有可能導致混亂,特別是當有許多類牽涉其中的時候。這麼做常常會造成一些微妙的、不容易發現的和初始化的次序有關的bug。除非你有絕對的必要使用類的單件,否則還是建議使用對象的單件,比較保險。

 

問:我還是不瞭解為何全局變數比單件模式差。

答:在.Net中,全局變數基本上就是對對象的靜態引用。在這樣的情況下使用全局變數會有一些缺點,我們已經提到了其中的一個,急切實例化VS延遲實例化。但是我們要記住這個模式的目的,確保類只有一個實例並提供全局訪問。全局變數可以提供全局訪問,但是不能確保只有一個實例。

三、代碼列表

public class Singleton
{
    //其他有用的單件數據

    private Singleton()
    {
    }

    //方式一:經典方式
    /*private static Singleton uniqueInstance;
    public static Singleton GetInstance()
    {
        if (uniqueInstance == null)
        {
            uniqueInstance = new Singleton();
        }
        return uniqueInstance;
    }*/

    //方式二:急切方式
    /*private static Singleton uniqueInstance = new Singleton();
    public static Singleton GetInstance()
    {
        return uniqueInstance;
    }*/

    //方式三:雙重檢查加鎖方式
    /*private static Singleton uniqueInstance;
    public static Singleton GetInstance()
    {
        if (uniqueInstance == null)
        {
            lock (uniqueInstance)
            {
                if (uniqueInstance == null)
                {
                    uniqueInstance = new Singleton();
                }
            }
        }
        return uniqueInstance;
        //Interlocked類為多個線程共用的變數提供原子操作。
        //CompareExchange方法比較兩個對象是否相等,如果相等,則替換其中一個對象。
        //return Interlocked.CompareExchange(ref uniqueInstance, new Singleton(), null);
    }*/

    //其他有用的單件方法
}
View Code

---------------------------------以上內容根據《Head First 設計模式》進行整理


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Restful是一種架構style,目前常說的有restful web service, resultful http。現在熱搜榜的微服務,大多數會採用Restful方式。 JAX-RS 作為一個Restful 風格WebService規範,目前已發展到了2.0版本,目前比較常用的兩個版本是JAX- ...
  • 用戶與訂單時一對多關係,再加上商品信息的話,訂單與商品之間就是多對多關係了 sql DROP DATABASE IF EXISTS testdb; USE testdb; / 用戶表,記錄用戶信息;用戶與訂單為一對多關係:一個用戶可擁有多個訂單 / DROP TABLE IF EXISTS ; CR ...
  • 緣起 因為一個月的短暫停留,我在給朋友搞事情,所以Yii系列的文章耽擱了很長時間,現在又重拾當時的知識,給大伙好好擼下這一系列的博客 提起Yii,雖然是國外的開發者搞的,但是它的作者是華人,這才是讓我們引以為豪的,如果以後有機會薛強回國大力發展PHP事業,我肯定回去他麾下搞事情,為PHP在國內的發展 ...
  • (一)Eclipse中的快捷鍵: ctrl+shift+f自動整理選擇的java代碼 alt+/ 生成無參構造器或者提升信息 alt+shift+s+o 生成帶參構造 ctrl+shift+o快速導入包 alt+shift+s+r tab+enter-->shift+tab+enter 快速生成ge ...
  • http://jingyan.baidu.com/article/e8cdb32b420ce737052badc4.html ...
  • JAVA 類總結 最近看了遍java內部類相關的一些內容,做一些總結。與個人博客 zhiheng.me 同步發佈,標題: JAVA 類總結。 頂級類與嵌套類 定義在某個類(或介面,下同)內部的類,稱為嵌套類(nested class),相應的,其所在的類稱之為該類的外圍類(enclosing cla ...
  • 一、環境搭建: 1、需要用的包: JUnit4.7:http://files.cnblogs.com/files/ShawnYang/junit4.7.zip hamcrest-1.2:http://files.cnblogs.com/files/ShawnYang/hamcrest-1.2.zip ...
  • 當你開發一個客戶端應用程式的時候,往往一個單頁會包含很多子模塊,在不同的平臺下,這些子模塊又被叫成子View(視圖),或者子Component(組件)。越是複雜的頁面,被切割出來的子模塊就越多,子模塊越多,彼此之間需要同步的數據和狀態就越頻繁,即易產生耦合。那麼如何保證在複雜業務情況下,各個子模塊之 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...