C#设计模式之单例模式实例讲解
前⾔
最近开始花点⼼思研究下设计模式,主要还是让⾃⼰写的代码可重⽤性⾼、保证代码可靠性。所谓设计模式,我了下定义:是⼀套被反复使⽤、多数⼈知晓的、经过分类编⽬的、代码设计经验的总结。毫⽆疑问,设计模式于⼰于他⼈于系统都是多赢的;设计模式使代码编制真正⼯程化;设计模式是软件⼯程的基⽯脉络,如同⼤厦的结构⼀样。
为什么要提倡“Design Pattern(设计模式)”?
根本原因是为了代码复⽤,增加可维护性。因此这次我们来学习下设计模式,最后会通过C#语⾔来实现这些设计模式作为例⼦,深刻理解其中的精髓。
定义
单例模式是⼀种常⽤的软件设计模式。在它的核⼼结构中只包含⼀个被称为单例类的特殊类。通过单例模式可以保证系统中⼀个类只有⼀个实例⽽且该实例易于外界访问,从⽽⽅便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在⼀个,单例模式是最好的解决⽅案。
特点
1、某个类只能有⼀个实例
2、它必须⾃⾏创建这个实例
3、它必须⾃⾏向整个系统提供这个实例。
优缺点
优点:
⼀、实例控制
单例模式会阻⽌其他对象实例化其⾃⼰的单例对象的副本,从⽽确保所有对象都访问唯⼀实例。
⼆、灵活性
因为类控制了实例化过程,所以类可以灵活更改实例化过程。
缺点:
⼀、开销
虽然数量很少,但如果每次对象请求引⽤时都要检查是否存在类的实例,将仍然需要⼀些开销。可以通过使⽤静态初始化解决此问题。
⼆、可能的开发混淆
使⽤单例对象(尤其在类库中定义的对象)时,开发⼈员必须记住⾃⼰不能使⽤new关键字实例化对象。因为可能⽆法访问库源代码,因此应⽤程序开发⼈员可能会意外发现⾃⼰⽆法直接实例化此类。
三、对象⽣存期
不能解决删除单个对象的问题。在提供内存管理的语⾔中(例如基于.NET Framework的语⾔),只有单例类能够导致实例被取消分配,因为它包含对该实例的私有引⽤。在某些语⾔中(如 C++),其他类可以删除对象实例,但这样会导致单例类中出现悬浮引⽤。
复制代码代码如下:
/// <summary>
/// 单例模式
/// </summary>
public class Singleton
{
// 定义⼀个静态变量来保存类的实例
private static Singleton mySingleton;
// 定义私有构造函数,使外界不能创建该类实例
private Singleton()
{
}
//定义公有⽅法提供⼀个全局访问点。
public static Singleton GetInstance()
{
/
/这⾥的lock其实使⽤的原理可以⽤⼀个词语来概括“互斥”这个概念也是操作系统的精髓
//其实就是当⼀个进程进来访问的时候,其他进程便先挂起状态
if (mySingleton == null)
{
mySingleton = new Singleton();
}
return mySingleton;
}
}
上⾯的单例模式的实现是有问题的,当多个⽤户或者⽅法同时访问的时候,便会出现多个⽤户同时拿到了mySingleton==null 的结果,这个明显不是我们想要的,因此,我们应该通过⼀个锁来互斥这个⽅法,当很多线程同时访问的时候,只允许⼀个线程进⼊到代码中执⾏,⽽其他的便只能处于挂起的状
态。
复制代码代码如下:
/// <summary>
/// 单例模式
/// </summary>
public class Singleton
单例模式的几种实现方式{
// 定义⼀个静态变量来保存类的实例
private static Singleton mySingleton;
// 定义⼀个标识确保线程同步
private static readonly object locker = new object();
/
/ 定义私有构造函数,使外界不能创建该类实例
private Singleton()
{
}
//定义公有⽅法提供⼀个全局访问点。
public static Singleton GetInstance()
{
//这⾥的lock其实使⽤的原理可以⽤⼀个词语来概括“互斥”这个概念也是操作系统的精髓
//其实就是当⼀个进程进来访问的时候,其他进程便先挂起状态
if (mySingleton == null)//区别就在这⾥
{
lock (locker)
{
// 如果类的实例不存在则创建,否则直接返回
if (mySingleton == null)
{
mySingleton = new Singleton();
}
}
}
return mySingleton;
}
}
其实在⼀些项⽬中,单例模式早就有了体现。在开发asp的项⽬中,就已经⽤这种⽅法来包装http上下⽂来实现计算机资源的节省。
复制代码代码如下:
/// <summary>
/// 业务仓储
/// </summary>
public IBLL.IBLLSession BLLSession;
//---------------------定义上下⽂属性
#region 实例构造函数初始化业务仓储 + OperateContext()
public OperateContext()
{
BLLSession = DI.SpringHelper.GetObject<IBLL.IBLLSession>("BLLSession");
}
#endregion
#region Http上下⽂以及相关属性
/// <summary>
/// Http上下⽂
/// </summary>
HttpContext ContextHttp
{
get
{
return HttpContext.Current;
}
}
HttpResponse Response
{
get
{
return ContextHttp.Response;
}
}
HttpRequest Request
{
get
{
return ContextHttp.Request;
}
}
HttpSessionState Session
{
get
{
return ContextHttp.Session;
}
}
#endregion
#region 获取当前操作上下⽂(存在线程中,提⾼效率) + OperateContext Current
// <summary>
/// 获取当前操作上下⽂(存在线程中,提⾼效率)
/// </summary>
public static OperateContext Current
{
get
{
OperateContext o = CallContext.GetData(typeof(OperateContext).Name) as OperateContext; if (o == null)
{
o = new OperateContext();
CallContext.SetData(typeof(OperateContext).Name, o);
}
return o;
}
}
#endregion
总结
到这⾥,就和⼤家⼀起先了解了单例模式到底是个什么东西,其实在⼀些项⽬中,这种模式就已经应⽤了,只是我们没有去发现和总结,不过本来设计模式就是⼀套被反复使⽤、多数⼈知晓的、经过分类编⽬的、代码设计经验的总结。哎。。。。这次是第⼆次编辑了,本来这个单例模式已经发布了好多天,竟然被我新的⼀篇观察者模式给覆盖了,数据取不回来,只能匆匆完稿,⼤家见谅啊,有问题我们⼀起来讨论,毕竟我也是初学者。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论