国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

.Net設計模式_單列模式

2019-11-14 16:52:48
字體:
來源:轉載
供稿:網友

理解

博友的經典說法:很多人排隊去廁所蹲坑一樣,每一次只能讓一個人去蹲坑,這是一種通俗的理解。

理論上的理解則為,我們需要寫一個類,這個類的作用就是控制,從而保證在整個應用程序的生命周期中,在任何時刻,被調用的類只有一個實例。

設計者需要為使用者提供一個該模式的一個全局訪問點。

 

代碼理解

入門實例:

public class Singleton {        PRivate static Singleton instance;        private Singleton()        {        }        public static Singleton GetInstance()        {            if (instance == null)            {                instance = new Singleton();            }            return instance;        } }

對代碼的理解:
1、保證在整個應用程序的生命周期中,在任何時刻,被調用的類只有一個實例。如何做到?

     第一點就是把類的構造函數私有化,這樣,調用者就不能通過New,來生成實例。

2、private static Singleton instance,該變量的作用,就是返回給調用者的類實例對象。

     因為該實例在生命周期中,是唯一的,所以定義一個私有的、靜態的、全局變量instance來保存該類的唯一實例。

3、上述的變量實例是一個私有的,而且我們把類的構造函數私有化了,那么我們就必須寫一個方法來返回類的實例對象。

     提供一個全局函數訪問,獲得instance實例,并且在該函數編寫控制實例數目的邏輯,即通過if語句判斷instance是否已被實例化,

     如果沒有則可以同new()創建一個實例;否則,直接向客戶返回一個實例。

注意:這種方式的實現對于線程來說并不是安全的,因為在多線程的環境下有可能得到Singleton類的多個實例。如果同時有兩個線程去判斷(instance == null),并且得到的結果為真,這時兩個線程都會創建類Singleton的實例,這樣就違背了Singleton模式的原則。實際上在上述代碼中,有可能在計算出表達式的值之前,對象實例已經被創建,但是內存模型并不能保證對象實例在第二個線程創建之前被發現。(這段話出之:http://m.survivalescaperooms.com/Terrylee/archive/2005/12/09/293509.html)

多線程實例:

public class Singleton{    private static Singleton instance;    private static object _lock = new object();    private Singleton()    {    }    public static Singleton GetInstance()    {        if (instance == null)        {            lock (_lock)            {                if (instance == null)                {                    instance = new Singleton();                }            }        }        return instance;    }}

對代碼的理解:
1、這段代碼與《入門實例》的區別在與,

  # 多了一個變量private static object _lock = new object()

      # 在公開方法中對該變量加了鎖

   # 在加鎖后,對實例做了判空處理

2、_lock變量申明為私有的、靜態的、全局變量的目的就是保證生命周期中的唯一,這樣對它加鎖后,線程模式下,就會出現加鎖等待。

3、內層的if語句塊中,對實例做了一個空判斷,解決了線程并發問題,同時避免在每個 Instance 屬性方法的調用中都出現獨占鎖定。

     它還允許您將實例化延遲到第一次訪問對象時發生。這種方式仍然有很多缺點:無法實現延遲初始化。

注意:這種模式是我們常用的

運行時實例:

public sealed class Singleton{    static readonly Singleton instance = new Singleton();    static Singleton()    {    }    private Singleton()    {    }    public static Singleton Instance    {        get        {            return instance;        }    }}

 對代碼的理解:

1、類的申明為sealed,阻止發生派生,而派生可能會增加實例

2、實例變量申明為readonly,這個是關鍵點(readonly為運行時常量)。

     第一次運行,會在全局的靜態存儲區域中初始化,因為是readonly的,所以就只會初始化一次,以后不會在變。

     這中方案的缺點是:對實例化機制的控制權較少,就是說你沒有調用實例,但實例對象已經生成。(我覺得無所謂)

3、我覺得不需要第二構造函數,不知道為啥,李大牛(http://m.survivalescaperooms.com/Terrylee/archive/2005/12/09/293509.html)的設計模式中添加了第二個構造函數。

   期待大家解惑(不寫,默認就是啊)。

     看完湯姆叔的http://m.survivalescaperooms.com/TomXu/archive/2011/12/19/2291448.html博客(慚愧),解惑。

延遲初始化實例:

public sealed class Singleton{    private Singleton()    {    }    public static Singleton Instance    {        get        {            return Nested.instance;        }    }    private class Nested    {        static Nested()        {        }        internal static readonly Singleton instance = new Singleton();    }}

 對代碼的理解:

1、這段代碼與《運行時實例》的區別就是,只有在你調用時,才會在生成實例到全局的靜態存儲區域中。

應用的場景:

我使用Microsoft.Practices.Unity容器在config中配置了依賴注入的實現,那么我需要去讀取這些配置,

<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">    <alias alias="" type="" />    <alias alias="" type="" />    <container name="XXXAdapter">    </container>    <container name="YYYAdapter">    </container></unity>
internal sealed class InitContainer{    private static IUnityContainer container;    private static readonly object _lock = new object();    private InitContainer()    {    }    public static IUnityContainer GetInstance()    {        if (container == null)        {            lock (_lock)            {                if (container == null)                {                    container = new UnityContainer();                    //獲取指定名稱的配置節                    UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");                    container.LoadConfiguration(section, "");                    container.LoadConfiguration(section, "");                }            }        }        return container;    }}

 這樣就保證只讀取一次的配置信息

 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 五峰| 龙州县| 万载县| 罗定市| 英超| 麦盖提县| 新余市| 博罗县| 德令哈市| 屏山县| 宁南县| 富锦市| 龙川县| 迁西县| 台前县| 昔阳县| 张家界市| 福贡县| 鹿邑县| 南丹县| 南木林县| 汉川市| 玛多县| 南岸区| 隆安县| 红河县| 嵩明县| 浦北县| 集安市| 囊谦县| 莱西市| 金秀| 称多县| 三明市| 定西市| 绍兴市| 桃江县| 桦甸市| 深水埗区| 沽源县| 武清区|