模式设计(四)Singleton

尽管在某种程度上,单件模式(Singleton Pattem)是限制而不是改进类的创建,但它仍和其他创建型模式分在一组。单件模式可以保证一个类有且只有一个实列。并提供一个访问它的全局访问点。在程序设计过程中,有很多情况需要确保一个类只有一个实列。例如,系统中只能有一个窗口管理器,一个打印假托机,或者一个数据引擎访问点。PC机中可能有几个串口,但只能有一个Com1实列。
 

单例模式的特点:

  • 单例类只能有一个实例。
  • 单例类必须自己创建自己的唯一实例。
  • 单例类必须给所有其它对象提供这一实例。

Singleton的设计方式大体上分为两种:
      1.使用静态方法创建单件,我们将用Pascal(定制)实现
      2.利用C#特有机制创建单件,我们将用C#来实现

下面我们看看利用C#特有机制创建单件的过程。为了方便起见我们在以前的SimFactory例子上作一些修改看看Singleton的实现过程。
UML图:

具体代码:

  1 None.gif using  System;
  2 None.gif
  3 None.gif namespace  Singleton
  4 ExpandedBlockStart.gifContractedBlock.gif dot.gif {
  5ExpandedSubBlockStart.gifContractedSubBlock.gif    /**//**//**//// <summary>
  6InBlock.gif    ///============== Program Description==============
  7InBlock.gif    ///Name:Singleton.cs
  8InBlock.gif    ///Objective:Singleton 
  9InBlock.gif    ///Date:2006-04-26 
 10InBlock.gif    ///Written By coffee.liu
 11InBlock.gif    ///================================================
 12ExpandedSubBlockEnd.gif    /// </summary>

 13InBlock.gif    class Class1
 14ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
 15ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//**//**//// <summary>
 16InBlock.gif        /// 应用程序的主入口点。
 17ExpandedSubBlockEnd.gif        /// </summary>

 18InBlock.gif        [STAThread]
 19InBlock.gif        static void Main(string[] args)
 20ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 21InBlock.gif            Thinking tk1,tk2,tk3;
 22InBlock.gif            PersonSimFactory PSF=new PersonSimFactory();
 23InBlock.gif            Person PP=PSF.GetPerson("Yellow");
 24InBlock.gif            tk1=PP.GetTk;
 25InBlock.gif            PP.GetInfo();
 26InBlock.gif            Console.WriteLine(".");
 27InBlock.gif            PP=PSF.GetPerson("Black");
 28InBlock.gif            tk2=PP.GetTk;
 29InBlock.gif            PP.GetInfo();
 30InBlock.gif            Console.WriteLine(".");
 31InBlock.gif            PP=PSF.GetPerson("Write");
 32InBlock.gif            tk3=PP.GetTk;
 33InBlock.gif            PP.GetInfo();
 34InBlock.gif            if ((tk1==tk2)&&(tk2==tk3)&&(tk1==tk3))
 35InBlock.gif                Console.WriteLine("we are the same Thinking");
 36InBlock.gif
 37ExpandedSubBlockEnd.gif        }

 38ExpandedSubBlockEnd.gif    }

 39ExpandedSubBlockStart.gifContractedSubBlock.gif    /**//**//**//// <summary>
 40InBlock.gif    /// 每个人都有思维
 41InBlock.gif    /// Thinking类被定为sealed类即不能被其他类继承
 42InBlock.gif    /// 我们把instance定义成了 static readonly属性,
 43InBlock.gif    /// 如果类中的static属性被任何方法使用时,.NET Framework将对这个属性进行初始化,
 44InBlock.gif    /// 于是在初始化Instance属性的同时Thinking类实例得以创建和装载。
 45InBlock.gif    /// 而私有的构造函数和readonly(只读)保证了Thinking不会被再次实例化,
 46InBlock.gif    /// 从而实现了Singleton的目的。
 47ExpandedSubBlockEnd.gif    /// </summary>

 48InBlock.gif
 49InBlock.gif    public sealed class Thinking  
 50ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
 51InBlock.gif        public static readonly Thinking instance=new Thinking();
 52ExpandedSubBlockStart.gifContractedSubBlock.gif        private Thinking()dot.gif{}
 53InBlock.gif       
 54InBlock.gif        public static Thinking Instance
 55ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 56InBlock.gif            get
 57ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
 58InBlock.gif                return instance;
 59ExpandedSubBlockEnd.gif            }

 60ExpandedSubBlockEnd.gif        }

 61ExpandedSubBlockStart.gifContractedSubBlock.gif        public void Say()dot.gif{
 62InBlock.gif        Console.WriteLine("I have a Thinking");
 63ExpandedSubBlockEnd.gif        }

 64InBlock.gif        
 65ExpandedSubBlockEnd.gif    }

 66InBlock.gif
 67InBlock.gif    public  class Person
 68ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
 69InBlock.gif        protected Thinking tk;
 70InBlock.gif        protected string sex,race;
 71InBlock.gif        public Thinking GetTk
 72ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 73ExpandedSubBlockStart.gifContractedSubBlock.gif            get dot.gif{return tk;}
 74ExpandedSubBlockEnd.gif        }

 75InBlock.gif        public string GetSex()
 76ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 77InBlock.gif            return sex;
 78ExpandedSubBlockEnd.gif        }

 79InBlock.gif        public string GetRace()
 80ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 81InBlock.gif            return race;
 82ExpandedSubBlockEnd.gif        }

 83InBlock.gif        public virtual void GetInfo()
 84ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 85ExpandedSubBlockEnd.gif        }

 86ExpandedSubBlockEnd.gif    }

 87InBlock.gif
 88InBlock.gif    public class YellowPerson:Person
 89ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
 90InBlock.gif        public YellowPerson()
 91ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 92InBlock.gif            sex="Man";
 93InBlock.gif            race="Yellow";
 94ExpandedSubBlockEnd.gif        }

 95InBlock.gif        public YellowPerson(string Ysex)
 96ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 97InBlock.gif            sex=Ysex;
 98InBlock.gif            race="Yellow";
 99ExpandedSubBlockEnd.gif        }

100InBlock.gif        public override void GetInfo()
101ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
102InBlock.gif            Console.WriteLine("the "+race+" Person Info:"+sex);
103InBlock.gif            tk=Thinking.Instance;
104InBlock.gif            tk.Say();
105ExpandedSubBlockEnd.gif        }

106ExpandedSubBlockEnd.gif    }

107InBlock.gif
108InBlock.gif    public class BlackPerson:Person
109ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
110InBlock.gif        public BlackPerson()
111ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
112InBlock.gif            sex="Man";
113InBlock.gif            race="Black";
114ExpandedSubBlockEnd.gif        }

115InBlock.gif        public BlackPerson(string Bsex)
116ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
117InBlock.gif            sex=Bsex;
118InBlock.gif            race="Black";
119ExpandedSubBlockEnd.gif        }

120InBlock.gif        public override void GetInfo()
121ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
122InBlock.gif            Console.WriteLine("the "+race+" Person Info:"+sex); 
123InBlock.gif             tk=Thinking.Instance;
124InBlock.gif            tk.Say();
125ExpandedSubBlockEnd.gif        }

126ExpandedSubBlockEnd.gif    }

127InBlock.gif
128InBlock.gif    public class WritePerson:Person
129ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
130InBlock.gif        public WritePerson()
131ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
132InBlock.gif            sex="Man";
133InBlock.gif            race="Write";
134ExpandedSubBlockEnd.gif        }

135InBlock.gif        public WritePerson(string Wsex)
136ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
137InBlock.gif            sex=Wsex;
138InBlock.gif            race="Write";
139ExpandedSubBlockEnd.gif        }

140InBlock.gif        public override void GetInfo()
141ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
142InBlock.gif            Console.WriteLine("the "+race+" Person Info:"+sex);
143InBlock.gif             tk=Thinking.Instance;
144InBlock.gif            tk.Say();
145ExpandedSubBlockEnd.gif        }

146ExpandedSubBlockEnd.gif    }

147InBlock.gif    public class PersonSimFactory
148ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
149ExpandedSubBlockStart.gifContractedSubBlock.gif        public PersonSimFactory()dot.gif{}
150InBlock.gif        public Person GetPerson(string RaceType)
151ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
152InBlock.gif            if (RaceType=="Yellow")
153InBlock.gif                return new YellowPerson();
154InBlock.gif            else
155InBlock.gif                if (RaceType=="Black")
156InBlock.gif                return new BlackPerson();
157InBlock.gif            else
158InBlock.gif                if (RaceType=="Write")
159InBlock.gif                return new WritePerson();
160InBlock.gif            else
161InBlock.gif                return new YellowPerson();
162InBlock.gif            
163ExpandedSubBlockEnd.gif        }

164ExpandedSubBlockEnd.gif    }

165ExpandedBlockEnd.gif}

166 None.gif

并且这样实现的Thinking类是线程安全的。
下面我们看看如何用Pascal语言,以类似静态方法来实现:
  1 None.gif program singleton;
  2 None.gif      //==============  Program Description ==============
  3 None.gif     // Name:singleton.dpr
  4 None.gif     // Objective:singleton
  5 None.gif     // Date : 2006 - 04 - 27
  6 None.gif     // Written By coffee.liu
  7 None.gif     //================================================
  8 None.gif{$APPTYPE CONSOLE}
  9 None.gif
 10 None.gifuses
 11 None.gif  SysUtils;
 12 ExpandedBlockStart.gifContractedBlock.gif  type Thinking = Class public class
 13InBlock.gif        public
 14ExpandedSubBlockStart.gifContractedSubBlock.gif        Class functionclass Function GetInstance()function GetInstance():Thinking;
 15InBlock.gif        作为Delphi来说,不能将contructor设为private,如果设为private,编译器将自动将
 16InBlock.gif        constructor更正为public
 17InBlock.gif        我们在这里重载NewInstance静态方法来控制构造函数防止其创建出多个实例
 18ExpandedSubBlockStart.gifContractedSubBlock.gif        Class functionclass Function NewInstance()function NewInstance:Tobject;override;
 19InBlock.gif        procedure FreeInstance;override;
 20InBlock.gif        public  procedure Say;
 21InBlock.gif  end;
 22ExpandedSubBlockStart.gifContractedSubBlock.gif  type Person=Class protectedclass
 23InBlock.gif       protected
 24InBlock.gif        sex:string;
 25InBlock.gif        race:string;
 26InBlock.gif        tk:Thinking;
 27ExpandedSubBlockStart.gifContractedSubBlock.gif        Property GetThinking()property GetThinking:Thinking read tk;
 28ExpandedSubBlockStart.gifContractedSubBlock.gif        public Function GetSex()function GetSex():string;
 29ExpandedSubBlockStart.gifContractedSubBlock.gif        public Function GetRace()function GetRace():string;
 30InBlock.gif        public procedure GetInfo;virtual;abstract;
 31InBlock.gif
 32InBlock.gif   end;
 33ExpandedSubBlockStart.gifContractedSubBlock.gif   type YellowPerson=Class (class(Person)
 34InBlock.gif       constructor YellowPerson();
 35InBlock.gif        public procedure GetInfo;override;
 36InBlock.gif     end;
 37ExpandedSubBlockStart.gifContractedSubBlock.gif    type BlackPerson=Class (class(Person)
 38InBlock.gif       constructor BlackPerson();
 39InBlock.gif        public procedure GetInfo;override;
 40InBlock.gif     end;
 41ExpandedSubBlockStart.gifContractedSubBlock.gif    type WritePerson=Class (class(Person)
 42InBlock.gif       constructor WritePerson();
 43InBlock.gif        public procedure GetInfo;override;
 44InBlock.gif     end;
 45ExpandedSubBlockStart.gifContractedSubBlock.gif    type PersonSimFactory=Class constructorclass
 46InBlock.gif        constructor PersonSimFactory();
 47ExpandedSubBlockStart.gifContractedSubBlock.gif        public Function GetPerson()function  GetPerson(RaceType:string):Person;
 48InBlock.gif         end;
 49InBlock.gifvar
 50InBlock.gifGlobalThinking:Thinking=nil;
 51InBlock.gifPSF:PersonSimFactory;
 52InBlock.gifPP:Person;
 53InBlock.gif{ Person }
 54InBlock.gif
 55ExpandedSubBlockStart.gifContractedSubBlock.gifFunction Person()function Person.GetRace: string;
 56InBlock.gifbegin
 57InBlock.gif result:=race;
 58InBlock.gifend;
 59InBlock.gif
 60ExpandedSubBlockStart.gifContractedSubBlock.gifFunction Person()function Person.GetSex: string;
 61InBlock.gifbegin
 62InBlock.gif  result:=sex;
 63InBlock.gifend;
 64InBlock.gif
 65InBlock.gif{ YellowPerson }
 66InBlock.gif
 67InBlock.gifconstructor YellowPerson.YellowPerson;
 68InBlock.gifbegin
 69InBlock.gif            sex:='Man';
 70InBlock.gif            race:='Yellow';
 71InBlock.gifend;
 72InBlock.gifprocedure YellowPerson.GetInfo;
 73InBlock.gif   begin
 74InBlock.gif    inherited;
 75InBlock.gif      WriteLn('the '+race+' Person Info:'+sex);
 76InBlock.gif   end;
 77InBlock.gif{ WritePerson }
 78InBlock.gif
 79InBlock.gifprocedure WritePerson.GetInfo;
 80InBlock.gifbegin
 81InBlock.gif  inherited;
 82InBlock.gif     WriteLn('the '+race+' Person Info:'+sex);
 83InBlock.gifend;
 84InBlock.gif
 85InBlock.gifconstructor WritePerson.WritePerson;
 86InBlock.gifbegin
 87InBlock.gif            sex:='Man';
 88InBlock.gif            race:='Write';
 89InBlock.gifend;
 90InBlock.gif
 91InBlock.gif{ BlackPerson }
 92InBlock.gif
 93InBlock.gifconstructor BlackPerson.BlackPerson;
 94InBlock.gifbegin
 95InBlock.gif            sex:='Man';
 96InBlock.gif            race:='Black';
 97InBlock.gifend;
 98InBlock.gif
 99InBlock.gifprocedure BlackPerson.GetInfo;
100InBlock.gifbegin
101InBlock.gif  inherited;
102InBlock.gif      WriteLn('the '+race+' Person Info:'+sex);
103InBlock.gifend;
104InBlock.gif
105InBlock.gif{ PersonSimFactory }
106InBlock.gif
107ExpandedSubBlockStart.gifContractedSubBlock.gifFunction PersonSimFactory()function PersonSimFactory.GetPerson(RaceType: string): Person;
108InBlock.gifbegin
109InBlock.gif
110InBlock.gif            if RaceType='Yellow' then
111InBlock.gif               result:=YellowPerson.YellowPerson
112InBlock.gif            else
113InBlock.gif            if RaceType='Black' then
114InBlock.gif                result:=BlackPerson.BlackPerson
115InBlock.gif            else
116InBlock.gif            if RaceType='Write' then
117InBlock.gif                 result:=WritePerson.WritePerson
118InBlock.gif            else
119InBlock.gif                 result:=YellowPerson.YellowPerson;
120InBlock.gif
121InBlock.gifend;
122InBlock.gif
123InBlock.gifconstructor PersonSimFactory.PersonSimFactory;
124InBlock.gifbegin
125InBlock.gif      inherited;
126InBlock.gifend;
127InBlock.gif{ Thinking }
128InBlock.gif
129InBlock.gifprocedure Thinking.FreeInstance;
130InBlock.gifbegin
131InBlock.gif  inherited;
132InBlock.gif  这里赋值nil是必要的,作为delphi来说一个对象被释放之后,它的实例对应的变量并不会自动设定为nil
133InBlock.gif  这里涉及到VMT的实现机理,具体情况请查看相关帮助
134InBlock.gif  GlobalThinking:=nil;
135InBlock.gifend;
136InBlock.gif
137ExpandedSubBlockStart.gifContractedSubBlock.gifClass functionclass Function Thinking()function Thinking.GetInstance: Thinking;
138InBlock.gifbegin
139InBlock.gif    if not Assigned(GlobalThinking)then
140InBlock.gif    GlobalThinking:=Thinking.Create();
141InBlock.gif    result:= GlobalThinking;
142InBlock.gifend;
143InBlock.gif
144ExpandedSubBlockStart.gifContractedSubBlock.gifClass functionclass Function Thinking()function Thinking.NewInstance: Tobject;
145InBlock.gifbegin
146InBlock.gif     if not Assigned(GlobalThinking)then
147InBlock.gif       GlobalThinking:=Thinking(inherited NewInstance);
148InBlock.gif       result:=GlobalThinking;
149InBlock.gifend;
150InBlock.gifprocedure Thinking.Say;
151InBlock.gif     begin
152InBlock.gif          WriteLn('I have a thinking!');
153InBlock.gif     end;
154InBlock.gifvar
155InBlock.gif tk1,tk2,tk3:Thinking;
156InBlock.gifbegin
157InBlock.gif   PSF:=PersonSimFactory.PersonSimFactory;
158InBlock.gif   PP:=PSF.GetPerson('Yellow');
159InBlock.gif   PP.GetThinking.Say;
160InBlock.gif   tk1:=PP.GetThinking;
161InBlock.gif   PP.GetInfo;
162InBlock.gif   WriteLn('dot.gifdot.gifdot.gifdot.gifdot.gifdot.gifdot.gifdot.gifdot.gifdot.gifdot.gif..');
163InBlock.gif   PP:=PSF.GetPerson('Black');
164InBlock.gif   PP.GetThinking.Say;
165InBlock.gif   tk2:=PP.GetThinking;
166InBlock.gif   PP.GetInfo;
167InBlock.gif   WriteLn('dot.gifdot.gifdot.gifdot.gifdot.gifdot.gifdot.gifdot.gifdot.gifdot.gifdot.gif..');
168InBlock.gif   PP:=PSF.GetPerson('Write');
169InBlock.gif   PP.GetThinking.Say;
170InBlock.gif   tk3:=PP.GetThinking;
171InBlock.gif   PP.GetInfo;
172InBlock.gif   WriteLn('dot.gifdot.gifdot.gifdot.gifdot.gif..errordot.gifdot.gifdot.gifdot.gif.');
173InBlock.gif   PP:=PSF.GetPerson('Write11');
174InBlock.gif   PP.GetThinking.Say;
175InBlock.gif   PP.GetInfo;
176InBlock.gif   if (tk1=tk2)and(tk2=tk3)then
177InBlock.gif     WriteLn('we are the same thinking!');
178InBlock.gifend.

下面我们再看一个现实中的例子,连接池的问题。许多应用程序需要访问存储在数据库和其他数据源。要访问数据库中的数据,应用程序就需要建立到数据库的连接。然后,应用程序就可以使用连接进行数据访问。建立数据库连接会花相对较长的时间,因为在建立连接的过程中数据库服务器和应用程序之间必须进行协商。数据库连接也会消耗宝贵的系统资源,如CPU处理能力,内存,网络带宽。因此,很值得研究和应用技术来减少建立数据库连接的需要和活动连接数量。在这个前提下我们来看看程序代码:
  1 None.gif using  System;
  2 None.gif using  System.Drawing;
  3 None.gif using  System.Collections;
  4 None.gif using  System.ComponentModel;
  5 None.gif using  System.Windows.Forms;
  6 None.gif using  System.Data;
  7 None.gif
  8 None.gif using  System.Data.SqlClient;
  9 ExpandedBlockStart.gifContractedBlock.gif     /**/ /// <summary>
 10InBlock.gif    ///============== Program Description==============
 11InBlock.gif    ///Name:PoolingTester.cs
 12InBlock.gif    ///Objective:PoolingTester 
 13InBlock.gif    ///Date:2006-04-26 
 14InBlock.gif    ///Written By coffee.liu
 15InBlock.gif    ///================================================
 16ExpandedBlockEnd.gif    /// </summary>

 17 None.gif namespace  ConnectionPooling
 18 ExpandedBlockStart.gifContractedBlock.gif dot.gif {
 19InBlock.gif   
 20InBlock.gif    public class PoolingTester : System.Windows.Forms.Form
 21ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
 22InBlock.gif        private System.Windows.Forms.Label label1;
 23InBlock.gif        private System.Windows.Forms.TextBox txtNumberOfConnections;
 24InBlock.gif        private System.Windows.Forms.Button btnConnect;
 25InBlock.gif        private System.Windows.Forms.Button btnDisconnect;
 26InBlock.gif        private System.Windows.Forms.CheckBox chkPooling;
 27InBlock.gif         Pooling PL;
 28ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
 29InBlock.gif        /// Required designer variable.
 30ExpandedSubBlockEnd.gif        /// </summary>

 31InBlock.gif        private System.ComponentModel.Container components = null;
 32InBlock.gif
 33InBlock.gif        public PoolingTester()
 34ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 35InBlock.gif            //
 36InBlock.gif            // Required for Windows Form Designer support
 37InBlock.gif            //
 38InBlock.gif            InitializeComponent();
 39InBlock.gif
 40InBlock.gif            // Enable the Connect button and 
 41InBlock.gif            // disable the Disconnect button
 42InBlock.gif            EnableButtons(false);
 43ExpandedSubBlockEnd.gif        }

 44InBlock.gif
 45ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
 46InBlock.gif        /// Clean up any resources being used.
 47ExpandedSubBlockEnd.gif        /// </summary>

 48InBlock.gif        protected override void Dispose( bool disposing )
 49ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 50InBlock.gif            if( disposing )
 51ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
 52InBlock.gif                if (components != null
 53ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
 54InBlock.gif                    components.Dispose();
 55ExpandedSubBlockEnd.gif                }

 56ExpandedSubBlockEnd.gif            }

 57InBlock.gif            base.Dispose( disposing );
 58ExpandedSubBlockEnd.gif        }

 59InBlock.gif
 60ContractedSubBlock.gifExpandedSubBlockStart.gif        Windows Form Designer generated code#region Windows Form Designer generated code
 61ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
 62InBlock.gif        /// Required method for Designer support - do not modify
 63InBlock.gif        /// the contents of this method with the code editor.
 64ExpandedSubBlockEnd.gif        /// </summary>

 65InBlock.gif        private void InitializeComponent()
 66ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 67InBlock.gif            this.btnDisconnect = new System.Windows.Forms.Button();
 68InBlock.gif            this.btnConnect = new System.Windows.Forms.Button();
 69InBlock.gif            this.txtNumberOfConnections = new System.Windows.Forms.TextBox();
 70InBlock.gif            this.label1 = new System.Windows.Forms.Label();
 71InBlock.gif            this.chkPooling = new System.Windows.Forms.CheckBox();
 72InBlock.gif            this.SuspendLayout();
 73InBlock.gif            // 
 74InBlock.gif            // btnDisconnect
 75InBlock.gif            // 
 76InBlock.gif            this.btnDisconnect.Location = new System.Drawing.Point(28040);
 77InBlock.gif            this.btnDisconnect.Name = "btnDisconnect";
 78InBlock.gif            this.btnDisconnect.Size = new System.Drawing.Size(9623);
 79InBlock.gif            this.btnDisconnect.TabIndex = 2;
 80InBlock.gif            this.btnDisconnect.Text = "Disconnect";
 81InBlock.gif            this.btnDisconnect.Click += new System.EventHandler(this.btnDisconnect_Click);
 82InBlock.gif            // 
 83InBlock.gif            // btnConnect
 84InBlock.gif            // 
 85InBlock.gif            this.btnConnect.Location = new System.Drawing.Point(2808);
 86InBlock.gif            this.btnConnect.Name = "btnConnect";
 87InBlock.gif            this.btnConnect.Size = new System.Drawing.Size(9623);
 88InBlock.gif            this.btnConnect.TabIndex = 2;
 89InBlock.gif            this.btnConnect.Text = "Connect";
 90InBlock.gif            this.btnConnect.Click += new System.EventHandler(this.btnConnect_Click);
 91InBlock.gif            // 
 92InBlock.gif            // txtNumberOfConnections
 93InBlock.gif            // 
 94InBlock.gif            this.txtNumberOfConnections.Location = new System.Drawing.Point(1768);
 95InBlock.gif            this.txtNumberOfConnections.Name = "txtNumberOfConnections";
 96InBlock.gif            this.txtNumberOfConnections.TabIndex = 1;
 97InBlock.gif            this.txtNumberOfConnections.Text = "";
 98InBlock.gif            // 
 99InBlock.gif            // label1
100InBlock.gif            // 
101InBlock.gif            this.label1.Location = new System.Drawing.Point(88);
102InBlock.gif            this.label1.Name = "label1";
103InBlock.gif            this.label1.Size = new System.Drawing.Size(16823);
104InBlock.gif            this.label1.TabIndex = 0;
105InBlock.gif            this.label1.Text = "Number of Connections:";
106InBlock.gif            // 
107InBlock.gif            // chkPooling
108InBlock.gif            // 
109InBlock.gif            this.chkPooling.Location = new System.Drawing.Point(840);
110InBlock.gif            this.chkPooling.Name = "chkPooling";
111InBlock.gif            this.chkPooling.Size = new System.Drawing.Size(26424);
112InBlock.gif            this.chkPooling.TabIndex = 3;
113InBlock.gif            this.chkPooling.Text = "Pool Connections";
114InBlock.gif            // 
115InBlock.gif            // PoolingTester
116InBlock.gif            // 
117InBlock.gif            this.AutoScaleBaseSize = new System.Drawing.Size(615);
118InBlock.gif            this.ClientSize = new System.Drawing.Size(38472);
119ExpandedSubBlockStart.gifContractedSubBlock.gif            this.Controls.AddRange(new System.Windows.Forms.Control[] dot.gif{
120InBlock.gif                                                                          this.chkPooling,
121InBlock.gif                                                                          this.btnDisconnect,
122InBlock.gif                                                                          this.btnConnect,
123InBlock.gif                                                                          this.txtNumberOfConnections,
124ExpandedSubBlockEnd.gif                                                                          this.label1}
);
125InBlock.gif            this.Name = "PoolingTester";
126InBlock.gif            this.Text = "ADO.NET Connection Pooling Test Form";
127InBlock.gif            this.ResumeLayout(false);
128InBlock.gif
129ExpandedSubBlockEnd.gif        }

130ExpandedSubBlockEnd.gif        #endregion

131InBlock.gif
132ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
133InBlock.gif        /// The main entry point for the application.
134ExpandedSubBlockEnd.gif        /// </summary>

135InBlock.gif        [STAThread]
136InBlock.gif        static void Main() 
137ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
138InBlock.gif            Application.Run(new PoolingTester());
139ExpandedSubBlockEnd.gif        }

140InBlock.gif
141InBlock.gif        // Connect to database
142InBlock.gif        private void btnConnect_Click(object sender, System.EventArgs e)
143ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
144InBlock.gif            //create Pooling object
145InBlock.gif            this.PL=Pooling.Instance;
146InBlock.gif            PL.Connect(Convert.ToInt32(txtNumberOfConnections.Text), chkPooling.Checked);
147InBlock.gif            EnableButtons(true);
148ExpandedSubBlockEnd.gif        }

149InBlock.gif
150InBlock.gif        // Disconnect from the database
151InBlock.gif        private void btnDisconnect_Click(object sender, System.EventArgs e)
152ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
153InBlock.gif            //create Pooling object
154InBlock.gif            this.PL=Pooling.Instance;
155InBlock.gif            PL.Disconnect();
156InBlock.gif            EnableButtons(false);
157ExpandedSubBlockEnd.gif        }

158InBlock.gif
159InBlock.gif        // Enable the Connect and Disconnect buttons depending on
160InBlock.gif        // whether or not it is connected to the database
161InBlock.gif        private void EnableButtons(bool Connected)
162ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
163InBlock.gif            btnConnect.Enabled = !Connected;
164InBlock.gif            btnDisconnect.Enabled = Connected;
165ExpandedSubBlockEnd.gif        }

166InBlock.gif
167InBlock.gif        
168ExpandedSubBlockEnd.gif    }

169InBlock.gif    sealed  class Pooling
170ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
171InBlock.gif        private static bool balancer=false;
172ExpandedSubBlockStart.gifContractedSubBlock.gif        private Pooling()dot.gif{}
173InBlock.gif        public static readonly Pooling instance=new Pooling();
174InBlock.gif      
175InBlock.gif        public static Pooling Instance
176ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
177InBlock.gif            get
178ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
179InBlock.gif                return instance;
180ExpandedSubBlockEnd.gif            }

181ExpandedSubBlockEnd.gif        }

182InBlock.gif        private ArrayList mConnectionArray = null;
183InBlock.gif        private const string mcConnString = 
184InBlock.gif            "Data Source=(local);" +
185InBlock.gif            "Integrated Security=SSPI;" +
186InBlock.gif            "Initial Catalog=Northwind";
187InBlock.gif        public  void Disconnect()
188ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
189InBlock.gif            
190InBlock.gif            balancer=true;
191InBlock.gif                foreach (SqlConnection cn in mConnectionArray)
192ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
193InBlock.gif                    cn.Close();
194ExpandedSubBlockEnd.gif                }
                      
195ExpandedSubBlockEnd.gif        }

196InBlock.gif        public void  Connect(int NumberOfConnections, bool PoolConnections)
197ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
198InBlock.gif              lock (typeof(Pooling))
199ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
200InBlock.gif            balancer=false;
201InBlock.gif                string ConnString = mcConnString + ";Pooling=" + PoolConnections;
202InBlock.gif
203InBlock.gif                mConnectionArray = new ArrayList(NumberOfConnections);
204InBlock.gif                for (int Idx = 0; Idx < NumberOfConnections; ++Idx)
205ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
206InBlock.gif                    SqlConnection cn = new SqlConnection(ConnString);
207InBlock.gif                    cn.Open();
208InBlock.gif                    mConnectionArray.Add(cn);
209ExpandedSubBlockEnd.gif                }

210ExpandedSubBlockEnd.gif            }

211ExpandedSubBlockEnd.gif        }

212ExpandedSubBlockEnd.gif    }

213ExpandedBlockEnd.gif}

214 None.gif

看看Pascal的实现:
  1 None.gif unit PoolingTester1;
  2 None.gif
  3 None.gifinterface
  4 None.gif
  5 None.gifuses
  6 None.gif  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  7 None.gif  Dialogs, StdCtrls,ADODB, DB;
  8 None.gif
  9 None.giftype
 10 None.gif  TForm1  =  class(TForm)
 11 None.gif    Button1: TButton;
 12 None.gif     procedure  Button1Click(Sender: TObject);
 13 None.gif  private
 14 None.gif    { Private declarations }
 15 None.gif   public
 16 None.gif    {  Public  declarations }
 17 None.gif   end ;
 18 None.gif const  mcConnString  = ' Provider=SQLOLEDB.1;Integrated Security=SSPI; '
 19 None.gif                 + ' Persist Security Info=False;User ID=sa;Initial Catalog=Northwind ' ;
 20 None.gif
 21 None.gif  type Pooling = class
 22 None.gif    private
 23 None.gif     mConnectionArray :TList;
 24 None.gif     public
 25 None.gif       procedure  Disconnect();
 26 None.gif       procedure  Connect(NumberOfConnections: integer ;PoolConnections:boolean);
 27 None.gif     Class   Function  GetInstance():Pooling;
 28 None.gif     class  Function  NewInstance():Tobject;override;
 29 None.gif      procedure  FreeInstance;override;
 30 None.gif
 31 None.gif   end ;
 32 None.gif var
 33 None.gif  Form1: TForm1;
 34 None.gif  CriticalSection:TRTLCriticalSection;
 35 None.gif GlobalPooling:Pooling = nil;
 36 None.gifimplementation
 37 None.gif
 38 None.gif{$R  * .dfm}
 39 None.gif
 40 None.gif{ Pooling }
 41 None.gif procedure  Pooling.Connect(NumberOfConnections:  integer ;
 42 None.gif  PoolConnections: boolean);
 43 None.gif var
 44 None.gifi: integer ;
 45 None.gifADOcnArr:array  of  TADOConnection;
 46 None.gifConnString:string;
 47 None.gif   begin
 48 None.gif  EnterCriticalSection(CriticalSection);  // 进入临界区
 49 None.gif    mConnectionArray: = TList. Create ;
 50 None.gif     setlength(ADOcnArr,NumberOfConnections);
 51 None.gif     for  i: = 0   to  NumberOfConnections - 1  do
 52 None.gif        begin
 53 None.gif        ConnString: =  mcConnString  +   ' ;Pooling= '   +  booltostr(PoolConnections,true);
 54 None.gif           ADOcnArr [ i ] : = TADOConnection. Create (Application);
 55 None.gif           ADOcnArr [ i ] .ConnectionString: = ConnString;
 56 None.gif           ADOcnArr [ i ] .LoginPrompt: = false;
 57 None.gif           ADOcnArr [ i ] .Connected: = true;
 58 None.gif           mConnectionArray. Add (ADOcnArr [ i ] );
 59 None.gif        end ;
 60 None.gif  LeaveCriticalSection(CriticalSection);     // 离开临界区
 61 None.gif end ;
 62 None.gif
 63 None.gif procedure  Pooling.Disconnect;
 64 None.gif var
 65 None.gifi: integer ;
 66 None.gif begin
 67 None.gif      for  i: = 0   to  mConnectionArray. Count - 1  do
 68 None.gif        begin
 69 None.gif          TADOConnection(mConnectionArray.Items [ i ] ).Connected: = false;
 70 None.gif        end ;
 71 None.gif end ;
 72 None.gif
 73 None.gif procedure  Pooling.FreeInstance;
 74 None.gif begin
 75 None.gif  inherited;
 76 None.gif    GlobalPooling: = nil;
 77 None.gif end ;
 78 None.gif
 79 None.gifclass  function  Pooling.GetInstance: Pooling;
 80 None.gif begin
 81 None.gif      if   not  Assigned(GlobalPooling) then
 82 None.gif  GlobalPooling: = Pooling. Create ;
 83 None.gif  result: =  GlobalPooling;
 84 None.gif
 85 None.gif end ;
 86 None.gif
 87 None.gifclass  function  Pooling.NewInstance: Tobject;
 88 None.gif begin
 89 None.gif    if   not  Assigned(GlobalPooling) then
 90 None.gif      GlobalPooling: = Pooling(inherited NewInstance);
 91 None.gif      result: = GlobalPooling;
 92 None.gif end ;
 93 None.gif
 94 None.gif
 95 None.gif procedure  TForm1.Button1Click(Sender: TObject);
 96 None.gif begin
 97 None.gif try
 98 None.gif   InitializeCriticalSection(CriticalSection);  // 初始化临界区
 99 None.gif   GlobalPooling: = Pooling. Create ;
100 None.gif   GlobalPooling.Connect( 20 ,true);
101 None.gif finally
102 None.gif    GlobalPooling.Disconnect;
103 None.gif  end ;
104 None.gif end ;
105 None.gif
106 None.gif end .

在这个例子中我们可以看到Pooling这个连接池类是个Singleton类。即无论PoolingTester被实例化多少次,我们Pooling只会被初始化一次。以上思路可以用在Web应用程序中,由于IIS本身是作为COM+应用程序安装的,就COM+而言,同一个Web应用程序中的所有网页都在一个进程中运行。因此,它们也可共享相同的连接库。

转载于:https://www.cnblogs.com/coffeeliu/archive/2006/04/26/385442.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值