今天我们来探索一下Singleton设计模式的实现及应用场景。

Singleton模式属于Creational Type(创建型)设计模式的一种。该模式一般用于确保在应用中仅创建一个某类的instance,在应用中的各个地方对该类的实例对象的引用均指向同一instacne。

Singleton模式的优势:它提供了对资源的concurrent(一致)访问,避免了创建多个实例对象,浪费内存空间。

Singleton模式实现准则:

1、确保仅有一个类的实例对象

2、提供对唯一实例对象的全局访问,该规则又可细分为3条规则。

  • 声明该类的所有构造器为private
  • 提供返回实例对象的引用的静态方法
  • 实例对象被存储为类的private static字段

下面通过例子实现Singleton模式,在具体实现时,我们首先实现不使用Singleton模式的代码,然后一步一步地将其改造成Singleton模式。

 namespace Singleton
{
class Program
{
static void Main(string[] args)
{
Singleton s1 = new Singleton();
s1.PrintMessage("this is first message"); Singleton s2 = new Singleton();
s2.PrintMessage("this is second message"); Console.ReadKey();
}
}
class Singleton
{
private static int counter = ;
public Singleton()
{
counter++;
Console.WriteLine("这是第"+counter.ToString()+"次调用构造函数");
}
public void PrintMessage(String str)
{
Console.WriteLine(str);
}
}
}

运行结果如下图:

  可以看出,在不使用Singleton模式时,每次使用类Singleton的PrintMessage方法时,都需要创建一个新的实例对象,这造成了极大的浪费。下面我们按照上面所说的准则将它改造成使用Singleton模式。

 namespace Singleton
{
class Program
{
static void Main(string[] args)
{
Singleton s1 = Singleton.getInstance;
s1.PrintMessage("this is first message"); Singleton s2 = Singleton.getInstance;
s2.PrintMessage("this is second message"); Console.ReadKey();
}
}
public sealed class Singleton
{
private static int counter = ;
private static Singleton instance=null; public static Singleton getInstance
{
get
{
if (instance == null)
instance = new Singleton();
return instance;
}
}
private Singleton()
{
counter++;
Console.WriteLine("这是第"+counter.ToString()+"次调用构造函数");
}
public void PrintMessage(String str)
{
Console.WriteLine(str);
}
}
}

运行结果如下图:

  另外,需要注意的是,不要忘了在Singleton类的声明中添加sealed关键字,它确保了Singleton类不可被继承。当Singleton类可被继承且继承类位于Singleton基类外部时,由于Singleton基类的构造函数声明为private,此时运行程序会产生Singleton.Singleton()受保护级别限制不可访问的编译错误;当Singleton类可被继承且继承类位于Singleton基类内部构成嵌套类时,这时在main()方法中就可以创建多个继承类的instance,这就违背了Singleton模式的设计初衷:仅能创建该类型的一个instance。

  最后,上述代码仅在单线程环境中运行良好,在下篇中介绍多线程环境中的实现,及Double-checked locking和lazy initialization的相关概念。

设计模式--Singleton_(1)(C#版)的更多相关文章

  1. 《大话设计模式》C#/C++版pdf/源码下载

    大话设计模式(带目录完整版)[中文PDF+源代码].zip 下载地址:http://pan.baidu.com/s/1giQP4大话设计模式C++.pdf下载地址:http://pan.baidu.c ...

  2. Java设计模式23种(搞笑版) (转)

        昨天做了一下支付宝的笔试题目被打击了,大量的逻辑推理和数学规律运算题目,其中还有问道Java设计模式的题目,一点都不知道,今天看到一份不错的介绍,非常好理解,作者是谁我没有办法考证,但是所有权 ...

  3. 设计模式学习笔记c++版——单例模式

    特别注意单例模式c++实现在main.cpp中引用的时候要去申明下: Singleton * Singleton::m_Instance = NULL; //定义性声明 不然会报错:无法解析的外部符号 ...

  4. java设计模式(六)--观察者模式

    转载:设计模式(中文-文字版) 目录: 简单目标任务实现 观察者模式介绍 观察者模式代码实现 观察者模式是JDK中使用最多的模式之一,非常有用.我们也会一并介绍一对多关系,以及松耦合(对,没错,我们说 ...

  5. Java设计模式学习资源汇总

    本文记录了Java设计模式学习书籍.教程资源.此分享会持续更新: 1. 设计模式书籍 在豆瓣上搜索了一把,发现设计模式贯穿了人类生活的方方面面.还是回到Java与程序设计来吧. 打算先归类,再浏览,从 ...

  6. Java经典23种设计模式之创造型模式(一)

    设计模式被称为程序猿的内功,之前零零散散的看过一大部分,但自己么有总结过.故此次在这里总结下.值得一提的是,设计模式并不是Java所特有.由于一直搞Android.这里就用Java为载体.最经典的设计 ...

  7. python设计模式之门面模式

    一.结构型设计模式 门面模式与单例模式,工厂模式不同,它是一种结构型模式. 结构型模式描述如何将对象和类组合成更大的结构 结构型模式是一种能够简化设计工作的模式,它能找出更简单的方法来认识或表示实体之 ...

  8. python设计模式之工厂模式

    一.理解工厂模式 在面向对象编程中,术语“工厂”表示一个负责创建替他类型对象的类.通常情况下,作为一个工厂的类有一个对象以及与它关联的多个方法.客户端使用某些参数调用此方法,之后,工厂会据此创建所需类 ...

  9. 什么时候使用PHP设计模式和为什么要使用?

    有大量的文章解释什么是设计模式,如何实现设计模式,网络上不需要再写一篇这样的文章.相反,在本文中我们更多的讨论什么时候用和为什么要用,而不是用哪一个和如何使用. 我将会为这些设计模式描绘不同的场景和案 ...

随机推荐

  1. maven不存在jar包解决

    win7环境 下载:https://maven.apache.org/download.cgi 提取文件,并cmd 转到bin目录 假设要添加的jar包是jbarcode-0.2.8.jar, 可执行 ...

  2. Loadrunner12.5-录制http://www.gw.com.cn/网页时提示“SSL身份验证失败”错误,这是为什么呢?

    问题:LR产品,录制http://www.gw.com.cn/ 网页时提示下图错误,这是为什么呢? 请在如下recording options中选择正确的SSL版本,再进行录制. 注:如何确定那个SS ...

  3. python不用声明数据类型

    不用声明变量一样,Python不用去声明函数的返回类型,是由于其“若类型”的语言特性决定的. 在其他语言中,例如C/C++语言中在存储一个数据之前,都需要在内存中给这个数据开辟一个固定的内存空间,并给 ...

  4. delphi XE7 数组操作中缺少的find(POS)功能

    delphi xe7 中对数组操作做了很多扩充,比如加入了类似字符串处理的功能. 例如,数组相加 var A: array of integer; B: TBytes = [1,2,3,4]; //I ...

  5. 2018.07.01 BZOJ3295: [Cqoi2011]动态逆序对(带修主席树)

    3295: [Cqoi2011]动态逆序对 **Time Limit: 10 Sec Memory Limit: 128 MB Description 对于序列A,它的逆序对数定义为满足i<j& ...

  6. 2018.09.08 poj1185 炮兵阵地(状压dp)

    传送门 状压dp经典题. 我们把每一行的状态压成01串. 预处理出每一行可能出现的状态,然后转移每个被压缩的状态的1的个数就行了. 注意当前行转移要考虑前两行的状态. 还要注意只有一行的情况. 代码: ...

  7. js 获取时间不能大于当前系统时间

    var dataDate=$.trim($("#dataDate").val()); if(dataDate.length==0){ $("#dataDateTip&qu ...

  8. Error setting expression 'XXX‘'[Ljava.lang.with value '[Ljava.lang.String;@10101fb'

    ognl报的警告,说明你的格式错误,一般是日期格式错误,格式转换器的应用,id设置的类型不对String 类型,输入了Int类型所以方法一是改变这个类中的id的属性 然后get和set也跟着改变 另一 ...

  9. oracle11g 导出空表

    --对已存在的表 执行如下 ,要经过统计分析后 num_rows=0 才准确select 'alter table '||table_name||' allocate extent;' from us ...

  10. WriteableBitmap(三) 扩展

    backbuffer使用您在创建WriteableBitmap时指定的像素格式,还有一个BackBufferStride属性,您可以使用它来创建一个合适的存储映射函数. 添加一些方法来设置和获取特定情 ...