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;
}
四. 代码实现
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
------------------------------------------------------------
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.客户端代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
{
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.代码实现
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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.客户端代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
el1.WriteEmalLog("发送Email给Jasmine。。。。");
EmailLog e21 = EmailLog.GetInstance();
e21.WriteEmalLog("发送给Email给tao feng li!.....");
Console.ReadKey();
3.运行结果
六.总结
单例模式是比较常用的。比较简单的设计模式。