理解

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

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

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

代码理解

入门实例:

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. Powershell profile.ps1 cannot be loaded because its operation is blocked by software restriction policies

    Powershell profile.ps1 cannot be loaded because its operation is blocked by software restriction pol ...

  2. Java之加密(信息摘要)工具类(依赖:java.security.MessageDigest或org.apache.commons.codec.digest.DigestUtils)

    依赖于java.security.MessageDigest,支持MD5,SHA-1,SHA-256 import java.security.MessageDigest; import java.s ...

  3. Linux 共享内存编程

    共享内存允许系统内两个或多个进程共享同一块内存空间,并且数据不用在客户进程和服务器进程间复制,因此共享内存是通信速度最快的一种IPC. 实现的机制简单描述如下:一个进程在系统中申请开辟了一块共享内存空 ...

  4. Fedora 21 安装桌面环境

    Mate桌面环境:$ sudo yum install @mate-desktop KDE桌面环境:$ sudo yum install @kde-desktop XFCE桌面环境:$ sudo yu ...

  5. sql server 数据库基础学习心得 思维导图

  6. #Leet Code# Divide Two Integers

    描述:不使用 * / % 完成除法操作.O(n)复杂度会超时,需要O(lg(n))复杂度. 代码: class Solution: # @return an integer def dividePos ...

  7. Quartz1.8.5例子(一)

    /* * Copyright 2005 - 2009 Terracotta, Inc. * * Licensed under the Apache License, Version 2.0 (the ...

  8. 【POJ1067】取石子游戏 (威佐夫博弈)

    [题目] Description 有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子:二是可以在两堆中同时取走相同数量的 ...

  9. Condition 的使用

    Condition 将 Object 监视器方法(wait.notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待 set ...

  10. bug修复复盘

    mybatis与数据库交互时,报了莫名其妙的错,日志中显示的Stack Trace中报错的代码行数与IDE中还一致,逐重启tomcat,异常消失. 故障复盘:没有重启tomcat,使用copy命令直接 ...