创建型模式之单件模式

先看这段vb.net代码:
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

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 NothingThen
                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(28888)
        
Me.Button1.Name = "Button1"
        Me.Button1.TabIndex = 0
        
Me.Button1.Text = "Button1"
        '
        'Button2
        '
        Me.Button2.Location = New System.Drawing.Point(408256)
        
Me.Button2.Name = "Button2"
        Me.Button2.TabIndex = 1
        
Me.Button2.Text = "Button2"
        '
        'Form1
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(513)
        
Me.ClientSize = New System.Drawing.Size(576382)
        
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.ObjectByVal e As System.EventArgs) Handles Button1.Click
        ForCom.getCom()
    
End Sub


    
Private Sub Button2_Click(ByVal sender As System.ObjectByVal 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

本文标题所指“单件模式”,条件改为 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;
        }


    }

}

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(20872);
            
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(304200);
            
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(513);
            
this.ClientSize = new System.Drawing.Size(456334);
            
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 物件混淆的危險。
posted @ 2005-08-09 11:06  Ready!  阅读(749)  评论(1编辑  收藏  举报