Design Patterns Simplified - Part 2 (Singleton)【設計模式簡述--第二部分(單例模式)】

来源:http://www.cnblogs.com/caofangsheng/archive/2016/08/05/5740800.html
-Advertisement-
Play Games

原文鏈接: http://www.c-sharpcorner.com/UploadFile/19b1bd/design-patterns-simplified-part-2-singleton/ Design Patterns Simplified - Part 2 (Singleton)【設計模式 ...


原文鏈接: http://www.c-sharpcorner.com/UploadFile/19b1bd/design-patterns-simplified-part-2-singleton/

Design Patterns Simplified - Part 2 (Singleton)【設計模式簡述--第二部分(單例模式)】

     

I am here to continue the explanation of Design Patterns. Today we will explain the easiest yet an important design pattern called Singleton.

這裡我繼續來解釋設計模式。今天我將會來解釋,最簡單但非常重要的設計模式,也就是單例模式。

In case you have not had a look at our first article, go through the following link:

這裡假設,你還沒有看我的第一篇文章,請先回去閱讀吧,下麵是鏈接:

Before talking about its implementation let’s begin with some fundamental questions as in the following. 

來討論單例模式是如何實現之前,我們先看看下麵一些基礎的問題吧。

Use of the Singleton Pattern【使用單例模式】

As the name suggests, the Singleton Pattern allows only one instance of a class to be created.

就像這個名字一樣,單例模式只允許,創建一個類的實例。

When do we need to have only one instance of a class? 

為什麼我們只需要一個類的實例?

There are many possible requiremetns for a instance of a class but they all tend to have the one objective that we don’t want to change the state of the object or we want to keep the class stateless.

這裡有許多可能的requiremetns類的實例,但是它們都想要只有一個對象,所以我們不能去改變對象的狀態或者使對象的狀態變成無效的。


A simple example could be that you want to load some master data at once and let the consumers of the data make a call to the Singleton class instead of each consumer making various calls by creating a new instance.

舉一個簡單的例子,你想要立刻載入主表的數據,並且讓一個單例類來調用獲取客戶表的數據,而不是對於每一個客戶,都來創建一個類的實例來調用獲取數據。

In general, in any complex enterprise application, Repository and Data Access Layer classes can be seen as a Singleton since typically we don’t want them to maintain the state in these layers.

一般來說,在任何複雜點的企業級應用程式中,倉儲和數據訪問層的類,可以作為單例來看待,因為我們不想要它們在這些層中,保持狀態。

Some other example could be cross-cutting concerns like Logging, Configuration, Caching and so forth that can also be implemented as a Singleton since we want a single and global point of access to these classes.
其他的例子就是橫切關註點了,例如日誌,系統配置,緩存等等,可以同樣設計為單例,因為我們想要對這些類,進行全局的,單一的訪問。


Apart from the core consideration explained above, I have seen that developers, mostly not so experienced sometimes, create unnecessarily instances that creates not just an overhead to memory but also impacts the overall performance of an application. 

除了上面解釋的,我看到過很多的開發者,有時候並不是那麼有經驗,他們創建不必要的實例,這不僅僅增加了記憶體的開銷,同樣也影響了系統的性能。

 

Why not Static classes【為什麼不使用靜態類】

There can be several reasons why to not use a static class however I can think of a few as follows.

至於為什麼不使用靜態類,我認為有如下的原因:

  • There can be cases where you want to implement interfaces (maybe to implement IOC, I will explain IOC later) in a class that can be done in a Singleton implementation but not in the static one.
     可能存在這樣的情況:你想要在類中實現某個介面【可能是實現IOC,我後面會降到IOC】,這種情況可以在單例中做到,但是不能在靜態類實現。
  • If required, you can use a singleton class as a method parameter whereas you cannot do that with a static class. 
         如果有需要,你可以把單例類作為一個方法的參數,但是,你不能對靜態類也這樣做。

Special care for Singleton classes【特別要說的就是單例類】

We need to take special care for Singleton classes. The idea of a state of a class comes with some extra care that means we need to handle synchronization issues in multi-threaded environments.

我們需要特別說到單例類,類的狀態,有一些需要註意點,也就是我們需要在多線程的環境中處理同步的問題。

Enough theory, now let’s talk about implementation.

好了,理論已經足夠了,現在我們來討論怎麼實現單例模式吧。

Let’s have a look at the most basic implementation.

我們先看看最基本的實現。

In the first example below, we have implemented a Singleton with Lazy loading since the instance will not be created until the caller calls the GetInstance method for the first time.

在下麵的例子中,我實現了一個懶載入的單例,因為這個實例只有在GetInstance方法第一次被調用的時候,才會創建類的實例。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    /// <summary>
    /// SingletonClass單例模式學習
    /// </summary>
   public class SingletonClass
    {
       /// <summary>
       /// 創建私有的,靜態的,類的變數
       /// </summary>
       private static SingletonClass instance = null;

       /// <summary>
       /// 創建私有的SingletonClass無參構造函數
       /// </summary>
       private SingletonClass() 
       {
       
       }

       /// <summary>
       /// 創建靜態的屬性GetInstance
       /// </summary>
       public static SingletonClass GetInstance
       {
           get 
           {
               if (instance == null)
               {
                   //實例化SingletonClass
                   instance = new SingletonClass();
               }
               return instance;
           }
       }
    }
}

Let’s try to fix the sync issue that may arise in multi-threaded environments. For this, we will use a double-lock mechanism.

現在我們來修複,上面例子中在多線程環境中,可能出現的同步問題吧。對於這個,我將會使用一個雙鎖機制。

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    /// <summary>
    /// SingletonClass單例模式學習
    /// </summary>
   public class SingletonClass
    {
       /// <summary>
       /// 創建私有的,靜態的,類的變數
       /// </summary>
       private static SingletonClass instance = null;


       private static object lockMe = new object();
       /// <summary>
       /// 創建私有的SingletonClass無參構造函數
       /// </summary>
       private SingletonClass() 
       {
       
       }

       /// <summary>
       /// 創建靜態的屬性GetInstance
       /// </summary>
       public static SingletonClass GetInstance
       {
           get 
           {
               if (instance == null)
               {
                   lock (lockMe)
                   {
                       if (instance == null)
                       {
                           //實例化SingletonClass
                           instance = new SingletonClass();
                       }
                   }
                  
               }
               return instance;
           }
       }
    }
}

 

And in the last, Singleton with static initializations. Please note that the .NET Framework guarantees thread safety for static initialization so we don’t need extra care for sync issues however we may not get the benefit of lazy loading of objects here. 

最後,我們看下單例模式靜態的初始化。請註意對於靜態的初始化,.NET Framework保證了線程安全,我們不必要去關心同步的問題,但是這種情況下,我們不能從懶載入對象中獲益。

 

public class SingletonClass 
{  
    private static SingletonClass instance = new SingletonClass();  
    private SingletonClass() {}  
    public static SingletonClass GetInstance 
    {  
        get 
        {  
            return instance;  
        }  
    }  
}   

 

I hope you have liked this article. I look forward to your comments/suggestions.

我希望你喜歡,這篇文章,期待你的評論和建議。

 

 


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

-Advertisement-
Play Games
更多相關文章
  • 函數的遞歸調用 遞歸的含義 遞歸其實也只是一種演算法上的描述,不是一種新的語法! 有時候,我們解決問題的時候,會遇到這種情況,當我們把一個大的問題按照某種解決方案分成若幹個小的問題的時候,發現這些小問題的解決方案其實和剛纔大問題的解決方案又是一樣的! 典型的,比如:求階乘! 10! = 10 * 9! ...
  • 最近由於公司慢慢往spark方面開始轉型,本人也開始學習,今後陸續會更新一些spark學習的新的體會,希望能夠和大家一起分享和進步。 Spark是什麼? Apache Spark™ is a fast and general engine for large-scale data processin ...
  • 一、總結 二、Bug描述:Mybatis中parameterType使用 mapper層中使用parameterType="java.lang.Integer"基本類型,代碼報錯: 解決辦法,當入參為基本數據類型的使用,使用_parameter代替基本數據類型,如下: 或者在mapper層的介面中, ...
  • 題意概括:那天以後,你好說歹說,都快煉成三寸不爛之舍之際,小A總算不在擺著死人臉,鼓著死魚眼。有了點恢復的徵兆。可孟子這家伙說的話還是有點道理,那什麼天將降....額,總之,由於賢者法陣未完成,而小A又遲遲不現身,FFF團團長連下七道聖火令追殺你們,最先趕到地,機械化部隊,它們除了智能不高外,可以說 ...
  • Spring AOP 的實現主要有兩種:CGLib與JDK自帶的Proxy。 他們主要的區別是,需要JDKProxy修改的類必須實現介面(因此也只能代理public方法),在創建Proxy時可以使用class.getInterfaces()獲得所有介面併進行代理。 而CGLib不受這個限制可以修改任 ...
  • 三大特性是:封裝,繼承,多態 所謂封裝 就是把客觀事物封裝成抽象的類,並且類可以把自己的數據和方法只讓可信的類或者對象操作,對不可信的進行信息隱藏.封裝是面向對象的特征之一,是對象和類概念的主要特性. 簡單的說,一個類就是一個封裝了數據以及操作這些數據的代碼的邏輯實體。在一個對象內部,某些代碼或某些 ...
  • A集成代碼生成器 [正反雙向(單表、主表、明細表、樹形表,開發利器)+快速構建表單;freemaker模版技術 ,0個代碼不用寫,生成完整的一個模塊,帶頁面、建表sql腳本,處理類,service等完整模塊B 集成阿裡巴巴資料庫連接池druid; 資料庫連接池 阿裡巴巴的 druid。Druid在監 ...
  • 原文鏈接:http://www.c-sharpcorner.com/UploadFile/19b1bd/design-patterns-simplified-part3-factory/ Design Patterns Simplified - Part 3 (Simple Factory)【設計模 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...