单例设计模式(李建忠老师)
singleton模式是所有设计模式当中最简单的一种模式,也是最基本的一种模式
在软件系统中,经常有这样一些特殊的类,必须保证它们在系统只只存在一个实例,才能确保它们的逻辑正确性,以及良好的效率,如何绕过常规的构造器,提供一种机制来保证一个类只有一个实例,下面就此问题展开分析。
有人可能会想:我只创建一个对象,然后告诉使用者你只能使用我创建的这个对象,你要是自己创建对象,你去死吧!!,我们要清楚一点,我们写的注释很少有人会去看(除了我们自己),所以如果你让别人去死,别人会活的很潇洒,因此我们不能用这种方式去保证系统的正确性,而是应该使其从语言上就做不到,这就是作为一个设计者的责任。
好吧,既然不能用这种激进的方式去实现我们的要求,那我们就来从语法上去规范它,常规的类不论我们写不写构造器都不行,因为就算你不写构造器,编译器也会生成一个缺省的构造器。
所以首先我们需要将构造器禁用掉(这里的禁用指的是只有类内能够访问,类外无法访问),那好,既然构造器被禁用掉了,那么在外部我们无法使用关键字new来创建对象了,只能用一个方法来返回一个在类内生成的对象,接下来,如果我们把这个方法定义为实例方法,实例方法必须依靠一个对象才能调用,而构造器已经被禁用,客户端根本无法创建对象,因此此方法必须定义成静态方法,接下来我们通过私有构造器定义一个该类的对象(也就是客户端能访问到的唯一的对象),并将其赋值为空,接下来我们需要在我们定义的静态方法里给它赋值,大家知道,静态方法是无法访问实例成员的,因此我们需要将该变量定义为静态的,下面我们先贴出代码:
class Singleton
{
int x;
int y;
private Singleton() //私有化构造器
{
}
static Singleton instance = null;
public static Singleton CreateSingleton()
{
if (instance == null)
{
instance = new Singleton(); //注意:这里由于instance为静态字段,因此其赋值需要调用静态构造器,但在这里我们并没有声明静态构造器,
//其实,当我们第一次使用静态字时,编译器会默认的帮我们生成一个静态构造器。这一点我们可以通过ildasm工具查看其IL代码证实。
}
return instance;
}
}
class Test
{
static void Main()
{
Singleton s1 = Singleton.CreateSingleton();
}
}
在CreateSingleton方法里,我们用了一个if 语句去判断对象是否是第一次被创建,如果是那就创建对象,如果不是,那就直接返回当前对象。
好了,我们似乎做到了,不仅保证了该类仅有一个实例,同时提供了一个该实例的全局访问点。
但是,事情并非我们想象的那么完美,这个设计模式仍然存在一些弊端,在实践编程的过程中,这个模式会发生多线程安全问题,我们来具体分析一下CreateSingleton这个方法,
假设线程1进入if语句,还未到达if语句的方法体中,此时实例对象instance仍然为空,此时控制权被线程2所掌握,进到if语句中进行判断,instance仍然为空,因此线程1和线程2将分别创建一个对象,这样的话系统里面会创建出两个对象。
此时就应该利用到静态构造器的线程安全来完成对象的创建,下面我贴出代码:
(这里我们采用的是内联初始化)
public class Singleton
{
int x;
int y;
private Singleton() //构造器私有化
{
}
public static readonly Singleton instance = new Singleton();//创建一个对象 ,这里调用的是静态构造器
}
public class Test
{
public static void main()
{
Singleton s1 = Singleton.instance;
}
}
在这里我们使用C#静态初始化机制实现了Singleton,且多线程安全。静态初始的过程中,对象的创建是同步的。
posted on 2011-10-14 17:15 guowenhui 阅读(1161) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架