NET设计模式3--单例模式(Singleton Pattern)

一. 单例模式

  单例模式,保证一个类只有一个实例,并提供一个访问它的全局访问点。单例模式因为Singleton封装它的唯一实例,它就可以严格的控制客户怎么访问它,以及何时访问它。

二.适用的场合

  当一个类只允许创建一个实例时,可以考虑使用单例模式。

三.单例模式的结构

  Singleton类,定义一个私有变量instance,私有构造方法Singleton()和方法GetInstance();

  私有变量instance;

  private static Singleton instance;

  私有构造方法Singleton(),外界不能使用new 关键字来创建此类的实例。

  private Singleton()

  {

  }

  方法GetInstance(),此方法是本类实例的唯一全局访问点。

  public static Singleton GetInstance()

  {

    //如实例不存在,则New一个新实例。否则返回已有实例

    if(instance==null)

    {

      instance=new Singleton();

    }

    return instance;

  }

四. 代码实现

  

代码
1.单例模式类Singleton
------------------------------------------------------------
 
public class SingletonClass
    {
        
private static SingletonClass instance;

        
/// <summary>
        
/// 程序运行时,创建一个静态只读的进程辅助对象
        
/// </summary>
        private static readonly object _object = new object();

        
/// <summary>
        
/// 构造方法私有,外键不能通过New类实例化此类
        
/// </summary>
        private SingletonClass()
        {

        }

        
public static SingletonClass GetInstance()
        {
            
//先判断实例是否存在,不存在再加锁处理
            if (instance == null)
            {
                
//在同一时刻加了锁的那部分程序只有一个线程可以进入
                lock (_object)
                {
                    
//如实例不存在,则NEW一个新实例,否则返回已有实例
                    if (instance == null)
                    {
                        instance 
= new SingletonClass();
                    }
                }
            }
            
return instance;
        }

    }

 

2.客户端代码

 

代码
        static void Main(string[] args)
        {
            SingletonClass sc1 
= SingletonClass.GetInstance();
            SingletonClass sc2 
= SingletonClass.GetInstance();
            
if (sc1 == sc2)
            {
                Console.WriteLine(
"实例sc1与实例sc2相同!");
            }
            Console.ReadKey();
        }

 

3.运行结果

  

五.实例分析

  1.场景

    Mail发送机制中,需要对已经发送的消息做Log。同一时间内只允许一个进程对txt文件进行操作,此时使用单件模式比较合适。

    WriteMailLog(string message)方法:记录Mail发送日志到文件

    _helper ,_fileLock:程序运行时,创建2个静态只读的进程辅助对象。

  2.代码实现

 

代码
EmailLog类
public class EmailLog
    {
        
private static object _helper = new object();
        
private static EmailLog _instance;
        
private static object _fileLock = new object();

        
private EmailLog()
        { }

        
public static EmailLog GetInstance()
        {
            
//先判断实例是否存在,不存在再加锁处理
            if (_instance == null)
            {
                
//在同一时刻加了锁的那部分程序只有一个线程可以进入
                lock (_helper)
                {
                    
if (_instance == null)
                    {
                        
//如实例不存在,则NEW一个新实例,否则返回已有实例
                        _instance = new EmailLog();
                    }
                }
            }
            
return _instance;
        }

        
public void WriteEmalLog(string message)
        {
            
string filePath = System.AppDomain.CurrentDomain.BaseDirectory + "mail.txt";

            StreamWriter sw 
= null;
            FileStream fs 
= null;

            
lock (_fileLock)
            {
                
//文件不存在,则新建文件
                if (!File.Exists(filePath))
                {
                    fs 
= System.IO.File.Create(filePath);
                    sw 
= new StreamWriter(fs, Encoding.UTF8);
                    sw.WriteLine(
"-----------------------------");
                    sw.WriteLine(message);
                    sw.Flush();
                    sw.Close();
                }
                
else//文件存在
                {
                    fs 
= new FileStream(filePath, FileMode.Append);
                    sw 
= new StreamWriter(fs, Encoding.UTF8);
                    sw.WriteLine(
"------------------------------");
                    sw.WriteLine(message);
                    sw.Flush();
                    sw.Close();
                }
            }
            

        }

    }

 

 

2.客户端代码

 

代码
            EmailLog el1=EmailLog.GetInstance();
            el1.WriteEmalLog(
"发送Email给Jasmine。。。。");
            EmailLog e21 
= EmailLog.GetInstance();
            e21.WriteEmalLog(
"发送给Email给tao feng li!.....");
            Console.ReadKey();

 

 

3.运行结果

 

 

六.总结

  单例模式是比较常用的。比较简单的设计模式。 

 

posted @ 2010-09-17 10:54  Jasmines  阅读(163)  评论(0编辑  收藏  举报