现在的位置: 首页 > 综合 > 正文

我读设计模式–Singleton Pattern

2012年04月30日 ⁄ 综合 ⁄ 共 5323字 ⁄ 字号 评论关闭
    之前在开发winform程序的时候,经常做这样的控制:每个form同时只能出现一个。方法有很多,通常我都采用这种方式:(通过一个public 的static 字段进行控制)
 主窗体menu:
private void subMenu1ToolStripMenuItem_Click(object sender, EventArgs e)
        
{
            
if (frm.sign == false)
            
{
                frm f 
= new frm();
                f.MdiParent 
= this;
                frm.sign 
= true;
                f.Show();
                
            }

            
else
            
{
                MessageBox.Show(
"该窗体已经存在~");
                
return;
            }


        }

frm窗体:

 public static bool sign = false;

        
public frm()
        
{    
           InitializeComponent();
        }


        
private void frm_FormClosing(object sender, FormClosingEventArgs e)
        
{
            sign 
= false;
        }

    这种方式可以很好的工作。
在Singleton Pattern,提到这种模式有几个特点:

  • 单例类只能有一个实例。
  • 单例类必须自己创建自己的唯一实例。 **
  • 单例类必须给所有其它对象提供这一实例。
    第二条中提到的,单例类只能自己控制,而不是由使用类的用户来控制单例(用户此时不知道是否单例),所以上述做法,虽然可以工作,但却不属于单件模式。
    namespace SingletonDemo2
    {
        
    class startMain
        
    {
            
    static void Main()
            
    {
                SingleTon instance1 
    = SingleTon.GetInstance();
                SingleTon instance2 
    = SingleTon.GetInstance();

                
    if (instance1 == instance2)
                
    {
                    Console.WriteLine(
    "equal");
                }

            }

        }

        
    class SingleTon
        
    {
            
    static SingleTon instance = new SingleTon(); //static:CLR 在类成员第一次被访问初始化static变量

            
    private SingleTon()  //private: 保证此类不能被实例化
            {
     
            }

            
    public static SingleTon GetInstance() 
            
    {
                
    return instance;
            }

        }


    }

    这是singleTon pattern的一般形式。
    应用单件模式也可以使上述实例很好的工作:
    frm:

     public partial class frm : Form
        
    {
            
    static frm f=null;

            
    public static frm GetInstance()
            
    {
                
    if (f == null || f.IsDisposed)
                
    {
                    f 
    = new frm();
                }

                
    return f;
            }


            
    private frm()
            
    {
                InitializeComponent();
            }

        }

    主窗体menu中:

    private void menuToolStripMenuItem_Click(object sender, EventArgs e)
            
    {
                frm f 
    = frm.GetInstance();
                f.MdiParent 
    = this;
                f.Show();
            }
  • 注意,多线程的程序中,上述简单写法让然可能造成多个实例,故而需要对线程安全性进行控制。
    1.双重锁定:

    Code

    2.静态初始化:

    Code

     

    单件模式的在多线程工作时更加有用。如果多个线程对一个类进行作业,如果各自产生自己的类实例,那结果必然是得不到我们的预期目的。这个时候,使用单件模式,使得不管有多少线程,工作的对象都只能是一个共同的实例,这才是我们想要的结果:(下面的例子引用自TerryLee的blog:多线程计数)

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Threading;

    namespace SingletonDemo2
    {
       
    public class Program
        
    {
           
    static void Main(string[] args)
           
    {
               MutilThreadCounter count 
    = new MutilThreadCounter();
               count.startMain();
           }

        }

        
    public class MutilThreadCounter
        
    {
            
    public MutilThreadCounter()
            
    {
     
            }

            
    public void doSomeWork()
            
    {
                
    string results = "";

                
    //获得单一实例
                Singleton Counter = Singleton.GetInstance();

                
    for (int i = 0; i < 5; i++)
                
    {
                    Counter.add();
                    
                    results 
    +="线程";
                    results 
    += Thread.CurrentThread.Name.ToString() + "——〉";
                    results 
    += "当前的计数:";
                    results 
    += Counter.getNum().ToString();
                    results 
    += "\n";

                    Console.WriteLine(results);
                    
                    
    /**////清空显示字符串
                    results = "";

                }

            }


            
    //多线程作业
            public void startMain()
            
    {
                Thread thread0 
    = Thread.CurrentThread;
                thread0.Name 
    = "thread0";

                Thread thread1 
    = new Thread(new ThreadStart(doSomeWork));
                thread1.Name 
    = "thread1";
               

                Thread thread2 
    = new Thread(new ThreadStart(doSomeWork));
                thread2.Name 
    = "thread2";

                Thread thread3 
    = new Thread(new ThreadStart(doSomeWork));
                thread3.Name 
    = "thread3";

                thread1.Start();
                thread2.Start();
                thread3.Start();

                doSomeWork();
            }


        }


        
    //单例类定义
        public class Singleton
        
    {
            
    //静态初始化
            static Singleton instance=new Singleton();

            
    private int num;

            
    public static Singleton GetInstance()
            
    {
                
    return instance;
            }

            
    public void add()
            
    {
                num
    ++;
            }

            
    public int getNum()
            
    {
                
    return num;
            }


            
    private Singleton()   //private保证不会被类的用户(类外部)被实例化
            {
            }

        }

    }

    以上只是对单例模式的应用做了个简单的总结,有关理论还是要参照大牛们的blog:
    http://terrylee.cnblogs.com/archive/2005/12/09/293509.html

    抱歉!评论已关闭.