C#中怎么實(shí)現(xiàn)單例模式

這期內(nèi)容當(dāng)中小編將會(huì)給大家?guī)碛嘘P(guān)C#中怎么實(shí)現(xiàn)單例模式,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

創(chuàng)新互聯(lián)專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都做網(wǎng)站、網(wǎng)站制作、永嘉網(wǎng)絡(luò)推廣、小程序開發(fā)、永嘉網(wǎng)絡(luò)營銷、永嘉企業(yè)策劃、永嘉品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);創(chuàng)新互聯(lián)為所有大學(xué)生創(chuàng)業(yè)者提供永嘉建站搭建服務(wù),24小時(shí)服務(wù)熱線:18982081108,官方網(wǎng)址:www.muchs.cn

單例模式的介紹


   2.1、動(dòng)機(jī)(Motivate)

          在軟件系統(tǒng)中,經(jīng)常有這樣一些特殊的類,必須保證它們在系統(tǒng)中只存在一個(gè)實(shí)例,才能確保它們的邏輯正確性、以及良好的效率。

   如何繞過常規(guī)的構(gòu)造器,提供一種機(jī)制來保證一個(gè)類只有一個(gè)實(shí)例?

         這應(yīng)該是類設(shè)計(jì)者的責(zé)任,而不是使用者的責(zé)任

   2.2、意圖(Intent)

         保證一個(gè)類僅有一個(gè)實(shí)例,并提供一個(gè)該實(shí)例的全局訪問點(diǎn)?!                       ?nbsp;          --《設(shè)計(jì)模式GoF》

   2.3、結(jié)構(gòu)圖(Structure)

       C#中怎么實(shí)現(xiàn)單例模式

  2.4、模式的組成

         (1)、單件實(shí)例(Singleton):這個(gè)模式里面只有一個(gè)類型,就是Singleton類型,并且這個(gè)類只有一個(gè)實(shí)例,可以通過Instance()方法獲取該類型的實(shí)例。

  2.5、單件模式的代碼實(shí)現(xiàn)

         既然是單實(shí)例,肯定會(huì)涉及到多線程的問題,我們就一步一步的來寫代碼,我們先看看單線程Singleton模式的實(shí)現(xiàn),代碼如下:

C#中怎么實(shí)現(xiàn)單例模式

    私有的實(shí)例構(gòu)造器是屏蔽外界的調(diào)用,上面的單例模式的實(shí)現(xiàn)在單線程下確實(shí)是完美的,也很好的滿足了我們單線程環(huán)境的需求。

    單線程單例模式的幾個(gè)要點(diǎn):

    (1)、Singleton模式中的實(shí)例構(gòu)造器可以設(shè)置為protected以允許子類派生。

    (2)、Singleton模式一般不要支持ICloneable接口,因?yàn)檫@可能會(huì)導(dǎo)致多個(gè)對(duì)象實(shí)例,與Singleton模式的初衷違背。

    (3)、Singleton模式一般不要支持序列化,因?yàn)檫@也有可能導(dǎo)致多個(gè)對(duì)象實(shí)例,同樣與Singleton模式的初衷違背。

    (4)、Singletom模式只考慮到了對(duì)象創(chuàng)建的工作,沒有考慮對(duì)象銷毀的工作。為什么這樣做呢,因?yàn)镹et平臺(tái)是支持垃圾回收的,所以我們一般沒有必要對(duì)其進(jìn)行銷毀處理。

    (5)、不能應(yīng)對(duì)多線程環(huán)境:在多線程環(huán)境下,使用Singleton模式仍然有可能得到Singleton類的多個(gè)實(shí)例對(duì)象


    如果放在多線程環(huán)境下,問題就出來了。因?yàn)樵趦蓚€(gè)線程同時(shí)運(yùn)行GetInstance方法時(shí),此時(shí)兩個(gè)線程判斷(uniqueInstance ==null)這個(gè)條件時(shí)都返回真,此時(shí)兩個(gè)線程就都會(huì)創(chuàng)建Singleton的實(shí)例,這樣就違背了我們單例模式初衷了。要想解決這個(gè)問題,只要讓GetInstance方法在同一時(shí)間只運(yùn)行一個(gè)線程運(yùn)行就好了,讓我們看看多線程Singleton模式的實(shí)現(xiàn),代碼如下:

C#中怎么實(shí)現(xiàn)單例模式

C#中怎么實(shí)現(xiàn)單例模式

    上面這種解決方案確實(shí)可以解決多線程的問題,但是上面代碼對(duì)于每個(gè)線程都會(huì)對(duì)線程輔助對(duì)象locker加鎖之后再判斷實(shí)例是否存在,對(duì)于這個(gè)操作完全沒有必要的,因?yàn)楫?dāng)?shù)谝粋€(gè)線程創(chuàng)建了該類的實(shí)例之后,后面的線程此時(shí)只需要直接判斷(uniqueInstance==null)為假,此時(shí)完全沒必要對(duì)線程輔助對(duì)象加鎖之后再去判斷,所以上面的實(shí)現(xiàn)方式增加了額外的開銷,損失了性能,為了改進(jìn)上面實(shí)現(xiàn)方式的缺陷,我們只需要在lock語句前面加一句(uniqueInstance==null)的判斷就可以避免鎖所增加的額外開銷,這種實(shí)現(xiàn)方式我們就叫它 “雙重鎖定(Double Check)”,下面具體看看實(shí)現(xiàn)代碼的:

C#中怎么實(shí)現(xiàn)單例模式

C#中怎么實(shí)現(xiàn)單例模式

       volatile修飾:編譯器在編譯代碼的時(shí)候會(huì)對(duì)代碼的順序進(jìn)行微調(diào),用volatile修飾保證了嚴(yán)格意義的順序。一個(gè)定義為volatile的變量是說這變量可能會(huì)被意想不到地改變,這樣,編譯器就不會(huì)去假設(shè)這個(gè)變量的值了。精確地說就是,優(yōu)化器在用到這個(gè)變量時(shí)必須每次都小心地重新讀取這個(gè)變量的值,而不是使用保存在寄存器里的備份。

三、C#中實(shí)現(xiàn)了單例模式的類

    現(xiàn)在我們看看,如何使用C#語言的特性來實(shí)現(xiàn)單例的Singleton模式。

C#中怎么實(shí)現(xiàn)單例模式

    內(nèi)聯(lián)初始化其實(shí)是把靜態(tài)的字段放到靜態(tài)構(gòu)造器去初始化。只要想訪問靜態(tài)字段,必定已經(jīng)在之前執(zhí)行了靜態(tài)構(gòu)造器。這樣也能夠精確地保證使用的時(shí)候一定能拿到實(shí)例,如果不使用也不會(huì)實(shí)例化對(duì)象,也就是延時(shí)加載的功能。他同樣能夠支持多線程環(huán)境,因?yàn)橹豢赡苡幸粋€(gè)線程執(zhí)行靜態(tài)構(gòu)造器,不可能有多個(gè)線程去執(zhí)行靜態(tài)構(gòu)造器,感覺就是程序已經(jīng)自動(dòng)為我們加鎖了。

     它的一點(diǎn)弊端就是它不支持參數(shù)化的實(shí)例化方法。在.NET里靜態(tài)構(gòu)造器只能聲明一個(gè),而且必須是無參數(shù)的,私有的。因此這種方式只適用于無參數(shù)的構(gòu)造器。

     需要說明的是:HttpContext.Current就是一個(gè)單例,他們是通過Singleton的擴(kuò)展方式實(shí)現(xiàn)的,他們的單例也并不是覆蓋所有領(lǐng)域,只是針對(duì)某些局部領(lǐng)域中,是單例的,不同的領(lǐng)域中還是會(huì)有不同的實(shí)例。

四、Singleton模式的擴(kuò)展

     (1)、將一個(gè)實(shí)例擴(kuò)展到n個(gè)實(shí)例,例如對(duì)象池的實(shí)現(xiàn)。(n不是指無限個(gè)實(shí)例,而是固定的某個(gè)數(shù))

     (2)、將new構(gòu)造器的調(diào)用轉(zhuǎn)移到其他類中,例如多個(gè)類協(xié)同工作環(huán)境中,某個(gè)局部環(huán)境只需要擁有某個(gè)類的一個(gè)實(shí)例。

     (3)、理解和擴(kuò)展Singleton模式的核心是“如何控制用戶使用new對(duì)一個(gè)類的實(shí)例構(gòu)造器的任意調(diào)用”。

五、單例模式的實(shí)現(xiàn)要點(diǎn)

      1、Singleton模式是限制而不是改進(jìn)類的創(chuàng)建。

      2、Singleton類中的實(shí)例構(gòu)造器可以設(shè)置為Protected以允許子類派生。

      3、Singleton模式一般不要支持Icloneable接口,因?yàn)檫@可能導(dǎo)致多個(gè)對(duì)象實(shí)例,與Singleton模式的初衷違背。

      4、Singleton模式一般不要支持序列化,這也有可能導(dǎo)致多個(gè)對(duì)象實(shí)例,這也與Singleton模式的初衷違背。

      5、Singleton只考慮了對(duì)象創(chuàng)建的管理,沒有考慮到銷毀的管理,就支持垃圾回收的平臺(tái)和對(duì)象的開銷來講,我們一般沒必要對(duì)其銷毀進(jìn)行特殊的管理。

      6、理解和擴(kuò)展Singleton模式的核心是“如何控制用戶使用new對(duì)一個(gè)類的構(gòu)造器的任意調(diào)用”。

      7、可以很簡單的修改一個(gè)Singleton,使它有少數(shù)幾個(gè)實(shí)例,這樣做是允許的而且是有意義的。

       1】、單例模式的優(yōu)點(diǎn):

             (1)、實(shí)例控制:Singleton 會(huì)阻止其他對(duì)象實(shí)例化其自己的 Singleton 對(duì)象的副本,從而確保所有對(duì)象都訪問唯一實(shí)例

             (2)、靈活性:因?yàn)轭惪刂屏藢?shí)例化過程,所以類可以更加靈活修改實(shí)例化過程

        2】、單例模式的缺點(diǎn):

             (1)、開銷:雖然數(shù)量很少,但如果每次對(duì)象請求引用時(shí)都要檢查是否存在類的實(shí)例,將仍然需要一些開銷??梢酝ㄟ^使用靜態(tài)初始化解決此問題。

             (2)、可能的開發(fā)混淆:使用 singleton 對(duì)象(尤其在類庫中定義的對(duì)象)時(shí),開發(fā)人員必須記住自己不能使用 new 關(guān)鍵字實(shí)例化對(duì)象。因?yàn)榭赡軣o法訪問庫源代碼,因此應(yīng)用程序開發(fā)人員可能會(huì)意外發(fā)現(xiàn)自己無法直接實(shí)例化此類。

             (3)、對(duì)象的生存期:Singleton 不能解決刪除單個(gè)對(duì)象的問題。因?yàn)樗瑢?duì)該靜態(tài)的私有字段的引用,靜態(tài)字段是不能被CLR回收內(nèi)存的,該實(shí)例會(huì)和應(yīng)用程序生命周期一樣長,一直存在。

       3】、單例模式的使用場合:

            (1)、當(dāng)類只能有一個(gè)實(shí)例而且客戶可以從一個(gè)眾所周知的訪問點(diǎn)訪問它時(shí)。

            (2)、當(dāng)這個(gè)唯一實(shí)例應(yīng)該是通過子類化可擴(kuò)展的,并且客戶應(yīng)該無需更改代碼就能使用一個(gè)擴(kuò)展的實(shí)例時(shí)。

上述就是小編為大家分享的C#中怎么實(shí)現(xiàn)單例模式了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

文章標(biāo)題:C#中怎么實(shí)現(xiàn)單例模式
當(dāng)前地址:http://www.muchs.cn/article0/ijcpio.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站導(dǎo)航、全網(wǎng)營銷推廣、ChatGPT、企業(yè)建站軟件開發(fā)、App設(shè)計(jì)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都做網(wǎng)站