索引

意图

保证一个类仅有一个实例,并提供一个访问它的全局访问点。

Ensure a class only has one instance, and provide a global point of access to it.

结构

参与者

Singleton

  • 定义一个 Instance 操作,允许客户访问它的唯一实例。Instance 是一个类操作。
  • 可能负责创建它自己的唯一实例。

适用性

在以下情况下可以使用 Singleton 模式:

  • 当类只能有一个实例并且客户可以从一个众所周知的访问点访问它时。
  • 当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。

缺点

  • 系统检查开销。实现中可能每次都需要检查实例是否存在,这个问题可以通过 Static 实例来解决。
  • 系统资源开销。通常 Singleton 中的对象一旦被创建,不会被及时销毁。可以通过提供 Reset 操作来重置。
  • 引起开发混淆。如果类包括 public 构造函数可以在外部构造,当使用 Singleton 对象时,开发人员需要记住不能使用 new 关键字来实例化对象。
  • 不易于测试。通常使用 Singleton 时需要考虑是否是反模式,设计是否存在问题。引入 Singleton 或静态实例会为 Unit Testing 带来困难。

效果

  • 对唯一实例的受控访问。
  • 缩小名空间。避免存储唯一实例的全局变量污染名空间
  • 允许对操作和表示的精化。Singleton 类可以有子类,通过扩展类在运行时刻配置应用。
  • 允许可变数目的实例。控制应用所使用的实例的数目。
  • 比类操作更灵活。比如使用静态成员函数。

相关模式

  • 很多模式可以使用 Singleton 模式实现。例如:Abstract Factory可以设计为 Singleton 实例。

实现

实现方式(一):使用 Static 变量初始化 Singleton。

在类加载时即创建实例。缺点是无论使用与否实例均被创建。

 namespace SingletonPattern.Implementation1
{
public class Singleton
{
private static Singleton _instance = new Singleton(); // the constructor should be protected or private
protected Singleton()
{
} public static Singleton Instance()
{
return _instance;
}
}
}

实现方式(二):使用 Lazy Initialization 来实现 Singleton

通常将创建类的唯一实例的操作隐藏在一个类操作后面,由它保证只有一个实例被创建。这个操作可以访问保存唯一实例的变量,保证在它的首次使用前被创建和初始化。

 namespace SingletonPattern.Implementation2
{
public class Singleton
{
private static Singleton _instance; // the constructor should be protected or private
protected Singleton()
{
} public static Singleton Instance()
{
if (_instance == null)
{
// use lazy initialization
_instance = new Singleton();
} return _instance;
}
}
}

实现方式(三):使用 Reset 来重置 Singleton

可以使用 Reset 操作来将已创建的实例销毁掉。

 namespace SingletonPattern.Implementation3
{
public class Singleton
{
private static Singleton _instance; // the constructor should be protected or private
protected Singleton()
{
} public static Singleton Instance()
{
if (_instance == null)
{
// use lazy initialization
_instance = new Singleton();
} return _instance;
} public void Reset()
{
_instance = null;
}
}
}

实现方式(四):使用 Double-Check Locking 技术实现 Singleton

Singleton 的实现如果需要保证线程安全性,则可以使用 Double-Check Locking 技术。

 namespace SingletonPattern.Implementation4
{
public class Singleton
{
private static Singleton _instance;
private static readonly object _syncRoot = new object(); // the constructor should be protected or private
protected Singleton()
{
} public static Singleton Instance()
{
// double-check locking
if (_instance == null)
{
lock (_syncRoot)
{
if (_instance == null)
{
// use lazy initialization
_instance = new Singleton();
}
}
} return _instance;
}
}
}

实现方式(五):使用注册表机制创建和查询 Singleton 类的子类实例

如果系统中定义了多个 Singleton 的子类,可以实现一个注册表机制,用于存储子类的映射。

 namespace SingletonPattern.Implementation5
{
public class Singleton
{
private static Dictionary<string, Singleton> _registry
= new Dictionary<string, Singleton>();
private static Singleton _instance; // the constructor should be protected or private
protected Singleton()
{
} public static Singleton Instance(string name)
{
if (!_registry.ContainsKey(name))
{
if (name == "Apple")
{
_registry.Add(name, new AppleSingleton());
}
else if (name == "Orange")
{
_registry.Add(name, new OrangeSingleton());
}
} return _registry[name];
}
} public class AppleSingleton : Singleton
{
} public class OrangeSingleton : Singleton
{
}
}

设计模式之美》为 Dennis Gao 发布于博客园的系列文章,任何未经作者本人同意的人为或爬虫转载均为耍流氓。

设计模式之美:Singleton(单件)的更多相关文章

  1. C#面向对象设计模式纵横谈——2.Singleton 单件(创建型模式)

    一:模式分类 从目的来看: 创建型(Creational)模式:负责对象创建. 结构型(Structural)模式:处理类与对象间的组合. 行为型(Behavioral)模式:类与对象交互中的职责分配 ...

  2. 设计模式之美:Creational Patterns(创建型模式)

    创建型模式(Creational Patterns)抽象了对象实例化过程. 它们帮助一个系统独立于如何创建.组合和表示它的那些对象. 一个类创建型模式使用继承改变被实例化的类. 一个对象创建型模式将实 ...

  3. 设计模式之美:Null Object(空对象)

    索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):Null Object 的示例实现. 意图 通过对缺失对象的封装,以提供默认无任何行为的对象替代品. Encapsulate t ...

  4. 设计模式之美:Object Pool(对象池)

    索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):实现 DatabaseConnectionPool 类. 实现方式(二):使用对象构造方法和预分配方式实现 ObjectPool ...

  5. 设计模式之美:State(状态)

    索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):由 ConcreteState 指定它的后继 State. 意图 允许一个对象在其内部状态改变时改变它的行为.对象看起来似乎修改 ...

  6. 设计模式之美:Facade(外观)

    索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):用抽象类定义 Facade 而使子类对应于不同的子系统. 意图 为子系统中的一组接口提供一个一致的界面,Facade 模式定义了 ...

  7. 设计模式之美:Abstract Factory(抽象工厂)

    索引 别名 意图 结构 参与者 适用性 缺点 效果 相关模式 命名约定 实现 实现方式(一):使用 Factory Method 来实现 Abstract Factory. 实现方式(二):使用 Pr ...

  8. 《设计模式之美》 <03>面向对象、设计原则、设计模式、编程规范、重构,这五者有何关系?

    面向对象 现在,主流的编程范式或者是编程风格有三种,它们分别是面向过程.面向对象和函数式编程.面向对象这种编程风格又是这其中最主流的.现在比较流行的编程语言大部分都是面向对象编程语言.大部分项目也都是 ...

  9. 设计模式之单例模式——Singleton

                        设计模式之单例模式--Singleton 设计意图: 保证类仅有一个实例,并且可以供应用程序全局使用.为了保证这一点,就需要这个类自己创建自己的对象,并且对外有 ...

随机推荐

  1. CentOS6.5 Openssl版本升级

    CentOS6.5  Openssl 升级: 第一步:在openssl官网(https://www.openssl.org/)下载最新版 Ps:个人使用的是openssl-1.0.1u.tar.gz版 ...

  2. JsonCpp的简单使用方法

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.易于人阅读和编写.同时也易于机器解析和生成.它基于JavaScript Programming Langu ...

  3. java 封装httpclient 的get 和post 请求

    import java.io.ByteArrayOutputStream; import java.io.UnsupportedEncodingException; import java.util. ...

  4. log4net注意事项

    log4net的配置信息可以直接配置在系统的配置文件中,也可以单独写一个配置文件,文件名随便起,如log4net.config,单独的文件属性“复制到输出目录”应该是true.因为log4net框架会 ...

  5. 创建 XMLHttpRequest 对象

    var _createHttpRequest = function () { var obj; if (window.XMLHttpRequest) obj = new XMLHttpRequest( ...

  6. Web页面多对象多文档事件冲突的解决方案

    这段时间写了很多基于js和jquery的前端控件,每一个的功能都很复杂,事件也很多. 因为都是单独封装的,单独使用没有问题,但把他们放到一个页面使用,就经常发生事件冲突的问题. 这几天一直在考虑用一个 ...

  7. CSS线性渐变

    /*CSS线性渐变*/ FILTER: progid:DXImageTransform.Microsoft.Gradient(gradientType=0,startColorStr=#ffffff, ...

  8. Action类为何要继承ActionSupport

    Action类为何要继承ActionSupport   理论上Struts 2.0的Action无须实现任何接口或继承任何类型,但是,我们为了方便实现Action,大多数情况下都会继承com.open ...

  9. (Unity)Unity自定义Debug日志文件,利用VS生成Dll文件并使用Dotfuscated进展混淆,避免被反编译

    Unity自定义Debug日志文件,利用VS生成Dll文件并使用Dotfuscated进行混淆,避免被反编译. 1.打开VS,博主所用版本是Visual Studio 2013. 2.新建一个VC项目 ...

  10. HTML之表单元素

    A.表单元素都是放在<form></form>标签内的.来看看表单的属性  属性 值 描述 accept MIME_type 规定通过文件上传来提交的文件的类型 accept- ...