理解

博友的经典说法:很多人排队去厕所蹲坑一样,每一次只能让一个人去蹲坑,这是一种通俗的理解。

理论上的理解则为,我们需要写一个类,这个类的作用就是控制,从而保证在整个应用程序的生命周期中,在任何时刻,被调用的类只有一个实例。

设计者需要为使用者提供一个该模式的一个全局访问点。

代码理解

入门实例:

public class Singleton
{
private static Singleton instance; private Singleton()
{ } public static Singleton GetInstance()
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}

对代码的理解:
1、保证在整个应用程序的生命周期中,在任何时刻,被调用的类只有一个实例。如何做到?

第一点就是把类的构造函数私有化,这样,调用者就不能通过New,来生成实例。

2、private static Singleton instance,该变量的作用,就是返回给调用者的类实例对象。

因为该实例在生命周期中,是唯一的,所以定义一个私有的、静态的、全局变量instance来保存该类的唯一实例。

3、上述的变量实例是一个私有的,而且我们把类的构造函数私有化了,那么我们就必须写一个方法来返回类的实例对象。

提供一个全局函数访问,获得instance实例,并且在该函数编写控制实例数目的逻辑,即通过if语句判断instance是否已被实例化,

如果没有则可以同new()创建一个实例;否则,直接向客户返回一个实例。

注意:这种方式的实现对于线程来说并不是安全的,因为在多线程的环境下有可能得到Singleton类的多个实例。如果同时有两个线程去判断(instance == null),并且得到的结果为真,这时两个线程都会创建类Singleton的实例,这样就违背了Singleton模式的原则。实际上在上述代码中,有可能在计算出表达式的值之前,对象实例已经被创建,但是内存模型并不能保证对象实例在第二个线程创建之前被发现。(这段话出之:http://www.cnblogs.com/Terrylee/archive/2005/12/09/293509.html

多线程实例:

public class Singleton
{
private static Singleton instance;
private static object _lock = new object(); private Singleton()
{ } public static Singleton GetInstance()
{
if (instance == null)
{
lock (_lock)
{
if (instance == null)
{
instance = new Singleton();
}
}
}
return instance;
}
}

对代码的理解:
1、这段代码与《入门实例》的区别在与,

  # 多了一个变量private static object _lock = new object()

# 在公开方法中对该变量加了锁

   # 在加锁后,对实例做了判空处理

2、_lock变量申明为私有的、静态的、全局变量的目的就是保证生命周期中的唯一,这样对它加锁后,线程模式下,就会出现加锁等待。

3、内层的if语句块中,对实例做了一个空判断,解决了线程并发问题,同时避免在每个 Instance 属性方法的调用中都出现独占锁定。

它还允许您将实例化延迟到第一次访问对象时发生。这种方式仍然有很多缺点:无法实现延迟初始化。

注意:这种模式是我们常用的

运行时实例:

public sealed class Singleton
{
static readonly Singleton instance = new Singleton(); static Singleton()
{
} private Singleton()
{
} public static Singleton Instance
{
get
{
return instance;
}
}
}

对代码的理解:

1、类的申明为sealed,阻止发生派生,而派生可能会增加实例

2、实例变量申明为readonly,这个是关键点(readonly为运行时常量)。

第一次运行,会在全局的静态存储区域中初始化,因为是readonly的,所以就只会初始化一次,以后不会在变。

这中方案的缺点是:对实例化机制的控制权较少,就是说你没有调用实例,但实例对象已经生成。(我觉得无所谓)

3、我觉得不需要第二构造函数,不知道为啥,李大牛(http://www.cnblogs.com/Terrylee/archive/2005/12/09/293509.html)的设计模式中添加了第二个构造函数。

   期待大家解惑(不写,默认就是啊)。

看完汤姆叔的http://www.cnblogs.com/TomXu/archive/2011/12/19/2291448.html博客(惭愧),解惑。

延迟初始化实例:

public sealed class Singleton
{
private Singleton()
{
} public static Singleton Instance
{
get
{
return Nested.instance;
}
} private class Nested
{
static Nested()
{
} internal static readonly Singleton instance = new Singleton();
}
}

对代码的理解:

1、这段代码与《运行时实例》的区别就是,只有在你调用时,才会在生成实例到全局的静态存储区域中。

应用的场景:

我使用Microsoft.Practices.Unity容器在config中配置了依赖注入的实现,那么我需要去读取这些配置,

<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<alias alias="" type="" />
<alias alias="" type="" />
<container name="XXXAdapter">
</container>
<container name="YYYAdapter">
</container>
</unity>
internal sealed class InitContainer
{
private static IUnityContainer container;
private static readonly object _lock = new object(); private InitContainer()
{
} public static IUnityContainer GetInstance()
{
if (container == null)
{
lock (_lock)
{
if (container == null)
{
container = new UnityContainer();
//获取指定名称的配置节
UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
container.LoadConfiguration(section, "");
container.LoadConfiguration(section, "");
}
}
} return container;
}
}

这样就保证只读取一次的配置信息

.Net设计模式_单列模式的更多相关文章

  1. 面向对象设计模式_命令模式(Command)解读

    在.Net框架中很多对象的方法中都会有Invoke方法,这种方法的设计实际是用了设计模式的命令模式, 模式图如下 其核心思路是将Client 向Receiver发送的命令行为进行抽象(ICommand ...

  2. Java 设计模式_代理模式(2016-08-19)

    概念: 代理模式是对象的结构模式.代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用. 就是一个人或者机构代表另一个人或者机构采取行动.在一些情况下,一个客户不想或者不能够直接引用一 ...

  3. java_设计模式_模板方法模式_Template Method Pattern(2016-08-11)

    定义: 定义一个操作中算法的骨架,而将一些步骤延迟到子类中,使得子类可以不改变算法的结构即可重定义该算法中的某些特定步骤.这里的算法的结构,可以理解为你根据需求设计出来的业务流程.特定的步骤就是指那些 ...

  4. java_设计模式_命令模式_Command Pattern(2016-08-09)

    理解还不到位,先窜出来.等过一阵子再看,再理解. 定义:将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能. 类型:行为类模式 类 ...

  5. spring设计模式_代理模式

    代理模式应该是Spring核心设计模式之一了 先说下代理模式特性: 1.有代理人和被代理人 2.对于被代理的人来说,这件事情是一定要做的,但是我又不想做,所有就找代理人来做. 3.需要获取到被代理人的 ...

  6. Spring设计模式_策略模式/其他

    策略模式特性 1.执行最终结果一样 2.执行过程和执行逻辑不一样 3.使用同一接口 达到目的就可以了 Git地址 https://github.com/wujiachengSH/WjcStrategy ...

  7. JAVA基础——设计模式之单列模式

    一:单例设计模式 Singleton是一种创建型模式,指某个类采用Singleton模式,则在这个类被创建后,只可能产生一个实例供外部访问,并且提供一个全局的访问点. 单例设计模式的特点: 单例类只能 ...

  8. java设计模式_工厂模式

    关于设计模式 设计模式(Design Pattern)是一套被反复使用.多数人知晓的.经过分类的.代码设计经验的总结,是一种设计思维,使用设计模式的目的:为了代码可重用性.让代码更容易被他人理解.保证 ...

  9. .Net设计模式_原型模式

    引言: 原型,感觉就是拷贝,只是给拷贝分了深拷贝和浅拷贝. 理解: 在C#.Net里面,我们可以很容易的通过Clone()方法实现原型模式. 任何类,只要想支持克隆,必须实现C#中的ICloneabl ...

随机推荐

  1. CSS 组合选择符

    CSS 组合选择符 组合选择符说明了两个选择器直接的关系. CSS组合选择符包括各种简单选择符的组合方式. 在 CSS3 中包含了四种组合方式: 后代选取器(以空格分隔) 子元素选择器(以大于号分隔) ...

  2. 【POJ1811】【miller_rabin + pollard rho + 快速乘】Prime Test

    Description Given a big integer number, you are required to find out whether it's a prime number. In ...

  3. php微信2 获取自定义菜单中的access_token

    //自定义菜单中获取access_token    static function get_access_token($appid,$secret){        $url="https: ...

  4. C#如何释放已经加载的图片 (转)

    使用Image.FromFile取磁盘上的图片时,这个方法会锁定图片文件,而且会导致内存占用增大, 有几种方法解决: 一:将Image类转换成Bitmap类 System.Drawing.Image ...

  5. fedora安装sublime text教程

    下载 http://pan.baidu.com/s/1eRkEegM 解压 终端中切换到下载文件的目录下,执行以下命令: sudo tar -jxvf sublime_text_3_build_308 ...

  6. LeetCode(4) || Longest Palindromic Substring 与 Manacher 线性算法

    LeetCode(4) || Longest Palindromic Substring 与 Manacher 线性算法 题记 本文是LeetCode题库的第五题,没想到做这些题的速度会这么慢,工作之 ...

  7. eclipse 启动tomcat报Spring错误 Error creating bean with name 'serviceOrderBiz': Injection of autowired dependencies failed

    启动tomcat报异常,提示Sring无法创建serviceOrderBiz(第一行红字),继续看是因为有一个自动注入的字段无法注入ModuleInterfaceBiz(第二行红字),检查servic ...

  8. BZOJ 2005 能量采集

    Description 栋栋有一块长方形的地,他在地上种了一种能量植物,这种植物可以采集太阳光的能量.在这些植物采集能量后,栋栋再使用一个能量汇集机器把这些植物采集到的能量汇集到一起. 栋栋的植物种得 ...

  9. 浅谈C# .Net技术面试 , 正在找工作的人一定要看看

    1.引子 最近一直在负责.net(B/S方向)技术面试相关的工作,前前后后面试了不少人,但是通过率较低,大概只有20%左右:有颇多感慨. 最近也一直比较困惑,原因究竟是什么? 是我们要求太高,应聘者本 ...

  10. 如何从 Xcode 控制台输出 JavaScript 的 log?

    调试 UIWebView 中的 JavaScript 一直以来都是很痛苦的一件事.通常我们会通过下面的方法调试 HTML 和 JavaScript. 1.第一种,使用桌面浏览器调试.大多数现代浏览器都 ...