乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      設計模式學習筆記(二)——Singleton單件模式

       skywood 2007-08-06

             這是我寫模式設計的第二篇,首先來說說設計模式的分類。

             基本的23種設計模式從目的上可分為三種:

      1、  創(chuàng)建型(Creational)模式:負責對象創(chuàng)建。

      2、  結構型(Structural)模式:處理類與對象間的組合,可以解決一些繼承依賴性的問題

      3、  行為型(Behavioral)模式:類與對象交互中的職責分配,可以解決組件間如何和交互,隔離變化。

      下面來說說單件模式:

      首先說說單件模式產(chǎn)生的動機,也就是為什么會出現(xiàn)單件模式。有一些類在系統(tǒng)中只存在一個實例才能確保他們的邏輯正確性以及良好的效率。這時我想到我遇到的一個問題。我曾經(jīng)遇到一個WinForm程序,運行后出現(xiàn)一個登陸框,輸入用戶名密碼后點擊登陸,然后顯示一個登陸后的界面。但是點擊登陸后,程序要做一些操作,由于這段操作用時相對較長,在不經(jīng)意時,我有點擊了一次登陸按鈕,最后出現(xiàn)了兩個對話框。如:我現(xiàn)在有兩個Form窗體Form1Form2。Form1上有一個按鈕用來打開Form2并隱藏自己。我們可以這樣寫:

               private void button1_Click(object sender, System.EventArgs e)

              {

                  Form2 form = new Form2();

                  form.Show();

                  this.Hide();

          }

      如果我們在顯示Form2前由一些比較耗時的操作。如:我們讓線程的沉睡10秒在顯示Form2,當我們在線程沉睡時繼續(xù)點擊Form1上的Button,有可能就會出現(xiàn)兩個Form2的窗體。(我試過可以出現(xiàn)兩個Form2,如果你有心試但沒事出來別拿西紅柿砍我,哈哈)

              private void button1_Click(object sender, System.EventArgs e)

              {

                  Thread.Sleep(10000);

                  Form2 form = new Form2();

                  form.Show();

                  this.Hide();

          }

      這種情況出現(xiàn)不能怪客戶多點了一下,也不能說是編譯器不夠智能,應該是我們程序上的Bug,我想這種情況用單件模式應該可以解決。

      單件模式的使用意圖就是:保證一個類僅有一個實例,并提供一個該實例全局的訪問點(這句話當然不是我先說的,是引用Gof在《設計模式》中的一句話)

      那類的設計者如何繞過常規(guī)的構造器來實現(xiàn)單件模式呢?下面就來談談單件模式的實現(xiàn)。

      單件模式在結構上使用了景泰方法來約束構造器(也就是構造函數(shù))創(chuàng)建對象。

      在單線程的情況下:私有化構造函數(shù),使類的使用者調(diào)用不到這個構造函數(shù)來new一個實例。類型中可以自己new一個實例。類中創(chuàng)建一個靜態(tài)私有變量和Static公有屬性。在公有屬性中實現(xiàn)此類的實例化。這樣在第一次請求時創(chuàng)建此對象。代碼如下:

      class Singleton

          {

              private static Singleton _instance;

             

              private Singleton(){}

       

              public static Singleton f_Instance

              {

                  get

                  {

                      if(_instance == null)

                      {

                          _instance = new Singleton();

                      }

                      return _instance;

                  }

              }

          }

      我在main函數(shù)中寫入如下程序來查看一下這樣寫是否有效:

      static void Main(string[] args)

              {

                  Singleton t1 = Singleton.f_Instance;

                  Singleton t2 = Singleton.f_Instance;

                  Console.Write(object.ReferenceEquals(t1,t2));

                  Console.Read();

              }

      控制臺顯示為True,開來還是有效的。當然在Main中我也試過這樣寫:Singleton t1 = new Singleton(),編譯時告訴我Singleton()不可訪問(當然,人家是私有的,不是自家人當然不見)

      這種單線程下的單件模式有幾點要注意:

      1、  構造器私有化(如果要此類被繼承,可以用protected聲明構造器)

      2、  不要支持IClinieable接口,因為會導致多個對象實例的出現(xiàn)

      3、  不能支持序列化

      4、  單件模式只考慮了對象創(chuàng)建的管理,沒有考慮對象的銷毀管理(創(chuàng)建自己的對象,銷毀的事交給垃圾回收器吧)

      5、  不能應對多線程環(huán)境,因為會導致多個對象實例的出現(xiàn)

      那在多線程下如何實現(xiàn)呢?代碼如下:

      class SingletonMuli//多線程Singleton模式

          {

              private static volatile SingletonMuli _instance;    //volatile是為了讓編譯器對此代碼編譯后的位置不進行調(diào)整

              private SingletonMuli(){}

              private static object lockHelper = new object();    //輔助器,不參與對象構建

              public static SingletonMuli f_Instance

              {

                  get

                  {

                      if(_instance == null)

                      {

                          lock(lockHelper)

                          {

                              if(_instance == null)       //雙檢查

                              {

                                  _instance = new SingletonMuli();

                              }

                          }

                      }

                      return _instance;

                  }

              }

          }

      當然還有一些更簡單的實現(xiàn)方法,如:

          class Singleton1//可以用在多線程環(huán)境

          {

              public static readonly Singleton1 _instance = new Singleton1();

              private Singleton1(){}

          }

      其中要提到的是在_instance私有字段的實例化叫做“內(nèi)聯(lián)初始化”。內(nèi)聯(lián)初始化是指在聲明時。

      實際上面的代碼上相當于如下代碼:

      Public static readonly Singleton1 _instance;

      Static Singleton()  //靜態(tài)構造函數(shù)

      {

          _instance = new Singleton();        //私有構造器

      }

      Private Singleton(){}

      內(nèi)聯(lián)初始化時會先執(zhí)行靜態(tài)構造器,如果沒有靜態(tài)構造函數(shù),系統(tǒng)會默認一個。在訪問此靜態(tài)字段時執(zhí)行靜態(tài)構造器生成。靜態(tài)構造器保證了在多線程時只有一個線程執(zhí)行,自動加鎖。

      當然,第二種實現(xiàn)方式也有一些缺點,如:靜態(tài)構造器必須是私有的、無參的。不過也可以用其他的方式解決這類問題。如可以用方法屬性實現(xiàn)擴展或修改私有構造器。

      現(xiàn)在我們可以回來看看我開始說的那兩個Form的問題,我們現(xiàn)在可以這樣實現(xiàn):

              private static Form2 form;

       

              private void button1_Click(object sender, System.EventArgs e)

              {

                  Thread.Sleep(10000);

                  object lockhelp = new object();

                  if(form == null)

                  {

                      lock(lockhelp)

                      {

                          if(form == null)

                          {

                              form = new Form2();

                              form.Show();

                          }

                      }

                  }

                  this.Hide();

              }

      這樣問題就解決了(我是沒有點出來第二個Form2,如果那位點出來了,給我發(fā)Email,我請她/他在天津的烤鴨)

      單件模式實際上是利用控制對象創(chuàng)造過程來控制對象的創(chuàng)造個數(shù)的方法,我們可以對其進行擴展,不是讓他只生成一個對象,可以讓他只生成幾個對象,這樣可以實現(xiàn)對象池。

      單件模式的核心是:如何控制用戶使用new對一個類的實例構造器的任意調(diào)用。

       

      posted on 2006-04-16 17:04 KiddLee 閱讀(1623) 評論(18)  編輯 收藏 引用 網(wǎng)摘 所屬分類: 設計模式

      FeedBack:
      # 
      private static object lockHelper = new object();
      你知道為什么要這樣寫嗎?

      而且,能顯示兩個窗體,正是EventHandler注冊了多個委托實例的原因,
      你修改后的button1_Click也并不是單件模式的應用.  回復  更多評論
        
      # re: 設計模式學習筆記(二)——Singleton單件模式 2006-04-16 18:12 Dflying Chen
      我也看不懂您的例子中Singleton的實現(xiàn)。  回復  更多評論
        
      # re: 設計模式學習筆記(二)——Singleton單件模式 2006-04-16 23:05 bisou.cn
      剛 開始看設計模式,有個疑問 就是Singleton和不用Singleton模式的類有什么區(qū)別?就是一個能夠保證一個實例,一個不能保證嗎?如果這樣的話大多類不都可以用這種形式 來做?除了一些特殊情況外?可為什么我看別人的代碼還是充斥著許多new呢?是他們不會用還是其他??
      望賜教  回復  更多評論
        
      # re: 設計模式學習筆記(二)——Singleton單件模式 2006-04-17 08:39 Terrylee
      @bisou.cn
      并不是大多數(shù)類都要用Singleton模式的,應該是大多數(shù)類都不用的,而只是那些少數(shù)資源比較昂貴的類才會用!  回復  更多評論
        
      # re: 設計模式學習筆記(二)——Singleton單件模式 2006-04-17 08:51 kid_li
      @aaaaaaa
      修改后的代碼我沒有拷貝完全,private static object lockHelper = new object(); 這句代碼聲明了一個輔助器,這是在下面為了鎖住資源使用的。出現(xiàn)兩個窗體是因為在程序運行時點擊了兩次Button1。我對Form程序的修改是按照多線 程單件模式的代碼事例寫的。  回復  更多評論
        
      # re: 設計模式學習筆記(二)——Singleton單件模式 2006-04-17 08:57 kid_li
      @Dflying Chen
      單件模式本質就是控制對象的構建,如果你把對象構建的方法給了類的使用者,你就無法控制類對象的構建個數(shù),要控制類對象的構建個數(shù),就要自己掌握類的構建方法,類的構建方法不被其他類使用者使用,所以,類的構建方法私有化可以達到限制的目的  回復  更多評論
        
      # re: 設計模式學習筆記(二)——Singleton單件模式 2006-04-17 09:03 kid_li
      @bisou.cn
      設計模式是一種思想,他也在不斷的擴展,正像我后面說的對象池,他就可以認為是一種單件模式的擴展。我有時間的話會再寫一篇利用單件模式的思想或擴展來實現(xiàn)對象池的代碼。有時間的話,請多多關注,多提意見  回復  更多評論
        
      # re: 設計模式學習筆記(二)——Singleton單件模式 2006-04-17 09:16 Dflying Chen
      @kid_li
      您的代碼里還在用form = new Form2();
      不也是調(diào)用了公有構造函數(shù)??
      難道在外面加了幾個lock就是Singleton?
      您的例子只能說是您在Form1中以Singleton的方式使用了Form2,而不能說Form2實現(xiàn)了Singleton模式………………
      如果真的使用了Singleton,應該寫form = Form2.Instance;才對…………  回復  更多評論
        
      # re: 設計模式學習筆記(二)——Singleton單件模式 2006-04-17 12:03 kid_li
      @Dflying Chen
      設計模式是思想,而不是固定的代碼片斷,使用設計模式是為了解決問題,而不是為了使用設計模式而使用設計模式。單件模式的實現(xiàn)也不是就我上面寫的 那幾種。有很多種寫法。而且這種思想本身也在發(fā)展。就我上面寫的那段WinForm的程序,我不用非要說明這是單件模式,我只想實現(xiàn)我的功能就可以。
      TerryLee曾和我說:設計模式就像打太極拳,要融會貫通,而不是循規(guī)蹈矩,當然很高興你跟我討論這個問題,不知這樣的解釋你是否滿意  回復  更多評論
        
      # re: 設計模式學習筆記(二)——Singleton單件模式 2006-04-17 14:54 henry
      (我是沒有點出來第二個Form2,如果那位點出來了,給我發(fā)Email,我請她/他在天津的烤鴨)
      針對這個功能的情況是沒問題的,因為無論你如何點擊或快速都是基于單線程操作,并沒有出現(xiàn)并發(fā)的情況.
      如果樓主沒有修改代碼的情況,那代碼應該不是線程安全的.
        回復  更多評論
        
      # re: 設計模式學習筆記(二)——Singleton單件模式 2006-04-17 16:02 bisou.cn
      @Terrylee

      按照你說的“只有少數(shù)資源比較昂貴的類才會用”的話,我就更不明白了,既然Singleton模式有這么多好處,比如可以減少資源的浪費和代碼輸入量的減少,為什么不只要能用的地方都用呢?這樣不是更好嗎?

      望 賜教! 其實就是這個問題我搞不懂,難道這個模式還是有缺點的(當然我是指在能用的情況下)  回復  更多評論
        
      # re: 設計模式學習筆記(二)——Singleton單件模式 2006-04-17 16:05 bisou.cn
      順便說一下,我看到好多講 Singleton單件模式 的時候 都會用到樓主以上的例子,包括微軟msdn上面的WebCast系列講座,但是每篇發(fā)表出來的blog都有人在下面質疑代碼!不知道到底這段代碼有什么問題  回復  更多評論
        
      # re: 設計模式學習筆記(二)——Singleton單件模式 2006-04-17 16:36 Terrylee
      @bisou.cn
      一下問這么多問題啊,呵呵,我慢慢來解釋吧:)
      1.“只有少數(shù)資源比較昂貴的類才會用”比如說NHibernate中的ISession實例,如果說再多線程情況下都去ISession實例的話,開銷會非常之大,所以這里就要使用Singleton模式。
      我一再說的是并不是所有的類都要用Singleton模式,比如說實體類,就無法使用。

      2.關于模式的優(yōu)缺點問題,可以說一句,設計模式是為了靈活性和擴展性、可維護性而存在的,并不是為了提高性能,相反是犧牲了性能來換取靈活性。 Singleton模式也有它自身的缺點,實例數(shù)量雖然減少了每次對象請求引用時都要檢查是否存在類的實例,還是需要一些開銷,所以這就是需要一個權衡的 過程!

      3.你說的那段代碼是指下面這段嗎?
      ======================================================
      class Singleton
      {
      private static Singleton _instance;

      private Singleton(){}

      public static Singleton f_Instance
      {
      get
      {
      if(_instance == null)
      {
      _instance = new Singleton();
      }
      return _instance;
      }
      }
      }
      ====================================================
      這段代碼是Single模式的一個簡單實現(xiàn),在單線程下是沒有問題的,但是如果是多線程,就會造成可能創(chuàng)建的實例不是一個,會有并發(fā)操作的問題,更多細節(jié)可以參考我寫的設計模式的文章:
      http://terrylee.cnblogs.com/archive/2005/12/09/293509.html

      4.還有一點,Singleton模式減少代碼輸入量的優(yōu)點從何談起呢?這一點我沒這樣說過,也沒體會到它會減少代碼輸入量。

      最后,個人認為Singleton模式僅僅是提供了保證類只有一個實例的這樣一種機制!具體使用那種實現(xiàn)方法,根據(jù)具體情況來定。比如說有人說 Doubl-Check有缺點,不能使用,但事實上在某些情況下還是可以使用,下面這段代碼出自于Enterprise Library2.0中:
      private static object sync = new object();
      private static volatile LogWriter writer;
      //得到創(chuàng)建LogWriter的工廠實例
      private static LogWriterFactory factory = new LogWriterFactory(ConfigurationSourceFactory.Create());

      public static LogWriter Writer
      {
      get
      {
      if (writer == null)
      {
      lock (sync)
      {
      if (writer == null)
      {
      try
      {
      //得到LogWriter對象
      writer = factory.Create();
      }
      catch (ConfigurationErrorsException configurationException)
      {
      TryLogConfigurationFailure(configurationException);

      throw;
      }
      }
      }
      }
      return writer;
      }
      }  回復  更多評論
        
      # re: 設計模式學習筆記(二)——Singleton單件模式 2006-04-17 17:31 henry
      模式本身是沒問題, 但在什么情況下如何實現(xiàn)是存在差別的.
      最常見的就是單線程和多線程下的處理,如果對這些問題沒有搞清楚的情況下使用是很危險的.
      如果我沒看錯源碼的情況下NHibernate中的ISession應該不是采用單件模創(chuàng)建的.
        回復  更多評論
        
      # re: 設計模式學習筆記(二)——Singleton單件模式 2006-04-17 17:42 Terrylee
      @henry
      暈,可能是我沒有說清楚,NHibernate源碼中的ISession是沒有用Singleton模式,我的意思是在我們自己創(chuàng)建ISession實例時,難道你也不用Singleton模式??
        回復  更多評論
        
      # re: 設計模式學習筆記(二)——Singleton單件模式 2006-04-17 18:06 henry
      @Terrylee
      SessionFactory我往往是采有單件模式保存.
      而ISession那看情況來定的,在Win下我通常會采用Singleton模式,但在web下我就不會選擇Singleton模式的.
      模式這東西我還是覺得在代碼重構過程中掌握會有更多的收益.  回復  更多評論
        
      # re: 設計模式學習筆記(二)——Singleton單件模式 2006-04-18 09:13 bisou.cn
      @Terrylee

      上文上的代碼輸入的減少我是指
      不用每個地方都需要Class1 class=new Class1()這樣寫了,后來想想確實沒有代碼量輸入的減少,呵呵

      因為我是做web的,基本上都是單線程,不用考慮多線程。所以說如果能用的我覺得都應該用。
      我想當然的覺得“每次對象請求引用時都要檢查是否存在類的實例”,比每次new一個實例應該對系統(tǒng)開銷要小的多! 當然我是想當然的,沒有試驗過 不知道對不對


      代碼質疑的是 Doubl-Check 這塊,我本以為微軟提供的webcast應該不會有什么問題的,呵呵
        回復  更多評論
        
      # re: 設計模式學習筆記(二)——Singleton單件模式 2006-04-18 10:33 Terrylee
      @henry,@bisou.cn
      從重構到模式是最好的使用設計模式的方法!

      我想這個問題的討論該結束了,再討論下去就會有人說我們無聊了,哈哈:-)

      這次的討論很愉快,以后多多交流!

        本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊一鍵舉報。
        轉藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多