索引

意图

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

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. 如何分隔两个base64字符串?

      如何分隔两个base64字符串?   用逗号或者任意的不在base64字符串内的字符都可以. All you have to do is to use a separator which is n ...

  2. JS --正则表达式验证、实战之邮箱模式

     JS验证格式:提高用户体验,验证文本. 需要防止程序员的代码结构更改攻击,因为web段的代码有可能会被更改,更改后JS有可能会验证不住那么,C#端在JS段通过验证的情况下,还需要进行二次验证 < ...

  3. NOI 2001 食物链(eat)

    1074 食物链 2001年NOI全国竞赛  时间限制: 3 s  空间限制: 64000 KB  题目等级 : 钻石 Diamond 题解  查看运行结果     题目描述 Description ...

  4. 【MVC】 js,css 压缩

    [MVC] js,css 压缩 一. 引用 System.Web.Optimization.dll : 使用 Nuget ,在控制台输入 Install-Package Microsoft.AspNe ...

  5. UI组件之Group

    当Group旋转或缩放时,它的孩子们正常绘制,并且Batch变换后正确的旋转或缩放. 绘制Group前,Batch flush使得变换可以设置.有很多Group时这将可能成为性能瓶颈.如果在一组演员不 ...

  6. oracle全文检索

    全文检索 oracle对使用几十万以上的数据进行like模糊查询速度极差,包括 like 'AAA%' ,like '%AAA',like '%AAA%',like '%A%A%'的那些模糊查询.网上 ...

  7. 双等位基因(biallelic sites )和多等位基因(multiallelic sites)

    双等位基因(biallelic sites ):表示在基因组的某个位点上有两个等位基因,如下图第七个位点所示,有G/-两种形式: 多等位基因(multiallelic sites):表示在基因组的某个 ...

  8. golang--gopher北京大会(1)

    大会感想:牛人真的很能写代码,实现很多功能,而且开源的精品越多,影响力越大,越能过上dream life.比如beego的作者,去了America,进入了Apple.另外,精英们特点是表达能力很强,也 ...

  9. 清除浮动的 why

    如果你想第三个p不被前面的浮动层所影响,就对它进行清除如果没有清除,第三个层就会移到第一个p下面 记住!!浮动是用来布局的~你看你的网页设计图,好几个版块在一条线上就是要浮动了,不需要浮动就是版块跟前 ...

  10. Linux crontab命令的使用方法

    crontab命令常见于Unix和Linux的操作系统之中,用于设置周期性被执行的指令.该命令从标准输入设备读取指令,并将其存放于"crontab"文件中,以供之后读取和执行. 在 ...