创建型模式之单件模式
先看这段vb.net代码:
com_counter 用来记录创建的实例的个数。
客户端应用:
如果要控制实例被创建的个数,比如要求只能建立3个该类的实例,就很简单了,把New()方法修改一下,像这样:
本文标题所指“单件模式”,条件改为 com_counter < 1 就可以了!
用C#:
关于Shared和static的用法:
Public Class ForCom
Public Shared com_counter As Integer
Private Shared glbCom As ForCom
Private legalInst As Boolean
Private Sub New()
glbCom = Me
com_counter = com_counter + 1
End Sub
Public Shared Function getCom() As ForCom
glbCom = New ForCom
Return glbCom '这里用getCom = glbCom也是可以的!
End Function
End Class
Public Shared com_counter As Integer
Private Shared glbCom As ForCom
Private legalInst As Boolean
Private Sub New()
glbCom = Me
com_counter = com_counter + 1
End Sub
Public Shared Function getCom() As ForCom
glbCom = New ForCom
Return glbCom '这里用getCom = glbCom也是可以的!
End Function
End Class
com_counter 用来记录创建的实例的个数。
客户端应用:
Public Class Form1
Inherits System.Windows.Forms.Form
'Inherits Aegis.Libs.Navigator.frmBasePlug
#Region " Windows Form Designer generated code "
Public Sub New()
MyBase.New()
'This call is required by the Windows Form Designer.
InitializeComponent()
'Add any initialization after the InitializeComponent() call
End Sub
'Form overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub
'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer
'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
Friend WithEvents Button1 As System.Windows.Forms.Button
Friend WithEvents Button2 As System.Windows.Forms.Button
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
Me.Button1 = New System.Windows.Forms.Button
Me.Button2 = New System.Windows.Forms.Button
Me.SuspendLayout()
'
'Button1
'
Me.Button1.Location = New System.Drawing.Point(288, 88)
Me.Button1.Name = "Button1"
Me.Button1.TabIndex = 0
Me.Button1.Text = "Button1"
'
'Button2
'
Me.Button2.Location = New System.Drawing.Point(408, 256)
Me.Button2.Name = "Button2"
Me.Button2.TabIndex = 1
Me.Button2.Text = "Button2"
'
'Form1
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(576, 382)
Me.Controls.Add(Me.Button2)
Me.Controls.Add(Me.Button1)
Me.Name = "Form1"
Me.Text = "Form1"
Me.ResumeLayout(False)
End Sub
#End Region
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
ForCom.getCom()
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
MsgBox(ForCom.com_counter.ToString())
End Sub
End Class
Inherits System.Windows.Forms.Form
'Inherits Aegis.Libs.Navigator.frmBasePlug
#Region " Windows Form Designer generated code "
Public Sub New()
MyBase.New()
'This call is required by the Windows Form Designer.
InitializeComponent()
'Add any initialization after the InitializeComponent() call
End Sub
'Form overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub
'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer
'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
Friend WithEvents Button1 As System.Windows.Forms.Button
Friend WithEvents Button2 As System.Windows.Forms.Button
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
Me.Button1 = New System.Windows.Forms.Button
Me.Button2 = New System.Windows.Forms.Button
Me.SuspendLayout()
'
'Button1
'
Me.Button1.Location = New System.Drawing.Point(288, 88)
Me.Button1.Name = "Button1"
Me.Button1.TabIndex = 0
Me.Button1.Text = "Button1"
'
'Button2
'
Me.Button2.Location = New System.Drawing.Point(408, 256)
Me.Button2.Name = "Button2"
Me.Button2.TabIndex = 1
Me.Button2.Text = "Button2"
'
'Form1
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(576, 382)
Me.Controls.Add(Me.Button2)
Me.Controls.Add(Me.Button1)
Me.Name = "Form1"
Me.Text = "Form1"
Me.ResumeLayout(False)
End Sub
#End Region
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
ForCom.getCom()
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
MsgBox(ForCom.com_counter.ToString())
End Sub
End Class
如果要控制实例被创建的个数,比如要求只能建立3个该类的实例,就很简单了,把New()方法修改一下,像这样:
Private Sub New()
If com_counter < 3 Then
glbCom = Me
com_counter = com_counter + 1
Else
Throw New Exception
End If
End Sub
If com_counter < 3 Then
glbCom = Me
com_counter = com_counter + 1
Else
Throw New Exception
End If
End Sub
本文标题所指“单件模式”,条件改为 com_counter < 1 就可以了!
用C#:
using System;
namespace WindowsApplication7
{
/// <summary>
/// Summary description for Class1.
/// </summary>
public class ForCom
{
public static Int32 com_counter = 0;
private static ForCom glbCom;
private bool legalInst;
private ForCom()
{
if (com_counter < 1)
{
glbCom = this;
com_counter = com_counter + 1;
legalInst = true;
}
else
{
legalInst = false;
throw new Exception();
}
}
public static ForCom getCom()
{
glbCom = new ForCom();
return glbCom;
}
}
}
namespace WindowsApplication7
{
/// <summary>
/// Summary description for Class1.
/// </summary>
public class ForCom
{
public static Int32 com_counter = 0;
private static ForCom glbCom;
private bool legalInst;
private ForCom()
{
if (com_counter < 1)
{
glbCom = this;
com_counter = com_counter + 1;
legalInst = true;
}
else
{
legalInst = false;
throw new Exception();
}
}
public static ForCom getCom()
{
glbCom = new ForCom();
return glbCom;
}
}
}
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
namespace WindowsApplication7
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Button button2;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.button2 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(208, 72);
this.button1.Name = "button1";
this.button1.TabIndex = 0;
this.button1.Text = "button1";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// button2
//
this.button2.Location = new System.Drawing.Point(304, 200);
this.button2.Name = "button2";
this.button2.TabIndex = 1;
this.button2.Text = "button2";
this.button2.Click += new System.EventHandler(this.button2_Click);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(456, 334);
this.Controls.Add(this.button2);
this.Controls.Add(this.button1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void button1_Click(object sender, System.EventArgs e)
{
ForCom.getCom();
}
private void button2_Click(object sender, System.EventArgs e)
{
System.Windows.Forms.MessageBox.Show(ForCom.com_counter.ToString());
}
}
}
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
namespace WindowsApplication7
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Button button2;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.button2 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(208, 72);
this.button1.Name = "button1";
this.button1.TabIndex = 0;
this.button1.Text = "button1";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// button2
//
this.button2.Location = new System.Drawing.Point(304, 200);
this.button2.Name = "button2";
this.button2.TabIndex = 1;
this.button2.Text = "button2";
this.button2.Click += new System.EventHandler(this.button2_Click);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(456, 334);
this.Controls.Add(this.button2);
this.Controls.Add(this.button1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void button1_Click(object sender, System.EventArgs e)
{
ForCom.getCom();
}
private void button2_Click(object sender, System.EventArgs e)
{
System.Windows.Forms.MessageBox.Show(ForCom.com_counter.ToString());
}
}
}
关于Shared和static的用法:
C# 所有的程式碼都要存放在 Class,VB.NET 持續支援標準模組。定義在標準模組的函數和變數會在 assembly 中以 global 的方式呈現。標準模組是與 CLS 相容的,C# 無法定義這一點。
C# 和 VB.NET 都在 Class 支援靜態方法、屬性和 fields(在 VB.NET 稱為 Shared)。它們在使用時不需真正建立物件,例如
class AClass
{
public static void StaticMethod()
{
Console.WriteLine("不需要建立物件就可以呼叫");
}
}
則呼叫 StaticMethod 只需要
AClass.StaticMethod();
在 C# 呼叫靜態方法只能透過 type 名稱,在 VB.NET 則同時可以利用 type 名稱或是物件的 instance 來呼叫,範例如下
Class AClass
Public Shared Sub ShareMethod()
Console.WriteLine("可以不建立物件來呼叫函數")
End Sub
End Class
可以透過以下兩種的程式碼使用
AClass.ShareMethod()
Dim a As New AClass()
a.ShareMethod()
這變成是哲理性的考量了,C# 提供了紀律:如果你想要建立與物件無關但以函數組成的函式庫(library),你必須建立 Class 來實際地將函數群組在一起,雖然你從來都不會為該 type 建立物件。由於所有的靜態成員仍需以 type 名稱來存取,會強制要求程式設計師明確知道該成員的共享特色。
VB.NET 提供了開發人員更大的彈性。你可以為一般功能函數建立傳統的標準模組,它可以在不指定任何 class 或模組名稱下直接使用。你可以存取物件的 instance 的 shared 成員,但這有讓 shared 物件與 instance 物件混淆的危險。
C# 和 VB.NET 都在 Class 支援靜態方法、屬性和 fields(在 VB.NET 稱為 Shared)。它們在使用時不需真正建立物件,例如
class AClass
{
public static void StaticMethod()
{
Console.WriteLine("不需要建立物件就可以呼叫");
}
}
則呼叫 StaticMethod 只需要
AClass.StaticMethod();
在 C# 呼叫靜態方法只能透過 type 名稱,在 VB.NET 則同時可以利用 type 名稱或是物件的 instance 來呼叫,範例如下
Class AClass
Public Shared Sub ShareMethod()
Console.WriteLine("可以不建立物件來呼叫函數")
End Sub
End Class
可以透過以下兩種的程式碼使用
AClass.ShareMethod()
Dim a As New AClass()
a.ShareMethod()
這變成是哲理性的考量了,C# 提供了紀律:如果你想要建立與物件無關但以函數組成的函式庫(library),你必須建立 Class 來實際地將函數群組在一起,雖然你從來都不會為該 type 建立物件。由於所有的靜態成員仍需以 type 名稱來存取,會強制要求程式設計師明確知道該成員的共享特色。
VB.NET 提供了開發人員更大的彈性。你可以為一般功能函數建立傳統的標準模組,它可以在不指定任何 class 或模組名稱下直接使用。你可以存取物件的 instance 的 shared 成員,但這有讓 shared 物件與 instance 物件混淆的危險。