C#面向对象设计模式纵横谈:Singleton 单件

  模式分类

  从目的来看:

  -创建型(Creational)模式:负责对象创建

  -结构型(Structural)模式:处理类与对象间的组合

  -行为型(Behavioral)模式:类与对象交互中的职责分配

  从范围来看:

  -类模式处理类与子类的静态关系

  -对象模式处理对象间的动态关系

  动机(Motivation)

  在软件系统中,经常有这样一些特殊的类,必须保证它们在系统中只存在一个实例,才能确保它们的逻辑正确性、以及良好的效率。如何绕过常规的构造器,提供一种机制来保证一个类只有一个实例?

这应该是类设计者的责任,而不是使用者的责任

  结构(Structure)

  单线程Singleton模式实现

  私有的实例构造器是为了屏蔽默认产生的构造器,让类的使用者无法调用构造器。

  单线程Singleton模式的几个要点

  Singleton模式中的实例构造器可以设置为protected以允许子类派生。

  Singleton模式一般不要支持ICloneable接口,因为这可能会导致多个对象实例,与Singleton模式的初衷违背。

  Singleton模式一般不要支持序列化,因为这也有可能导致多个对象实例,同样与Singleton模式的初衷违背。

  Singleton模式只考虑到了对象创建的管理,没有考虑对象销毁的管理。就支持垃圾回收平台和对象的开销来讲,我们一般没有必要对其销毁进行特殊的管理。

  不能应对多线程环境:在多线程环境下,使用Singleton模式仍然有可能得到Singleton类的多个实例对象。

  多线程Singleton模式实现

  volatile修饰:编译器在编译代码的时候会对代码的顺序进行微调,用volatile修饰保证了严格意义的顺序。一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。

  使用.NET类型初始化机制实现多线程Singleton模式

  以上是内联初始化(生成的同时进行初始化)的单例模式,它等同于:

  内联初始化其实是把静态的字段放到静态构造器去初始化。反编译出内联初始化的代码可以看出以上结论

  只要想访问静态字段,必定已经在之前执行了静态构造器。这样也能够精确地保证使用的时候一定能拿到实例,如果不使用也不会实例化对象,也就是延时加载的功能。他同样能够支持多线程环境,因为只可能有一个线程执行静态构造器,不可能有多个线程去执行静态构造器,感觉就是程序已经自动为我们加锁了。

  它的一点弊端就是它不支持参数化的实例化方法。在.NET里静态构造器只能声明一个,而且必须是无参数的,私有的。因此这种方式只适用于无参数的构造器。

  Singleton模式扩展
  将一个实例扩展到n个实例,例如对象池的实现。(n不是指无限个实例,而是固定的某个数)将new构造器的调用转移到其他类中,例如多个类协同工作环境中,某个局部环境只需要拥有某个类的一个实例。理解和扩展Singleton模式的核心是“如何控制用户使用new对一个类的实例构造器的任意调用”。

  .NET框架中的Singleton应用

  t1==t2 这说明,GetType方法获得的Type实例都是单例。HttpContext.Current也是如此,他们是通过Singleton的扩展方式实现的,他们的单例也并不是覆盖所有领域,只是针对某些局部领域中,是单例的,不同的领域中还是会有不同的实例。

  推荐参考书

  《设计模式:可复用面向对象软件的基础》 GoF

  《面向对象分析与设计》 Grady Booch  

  《敏捷软件开发:原则、模式与实践》 Robert C.Martin

  《重构:改善既有代码的设计》 Martin Fowler

  《Refactoring to Patterns》 Joshua Kerievsky

  2010.9.21

时间: 2024-08-01 09:51:18

C#面向对象设计模式纵横谈:Singleton 单件的相关文章

设计模式之Singleton

设计 设计模式之SingletonSingleton定义:Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在. 在很多操作中,比如建立目录 数据库连接都需要这样的单线程操作. 还有, singleton能够被状态化; 这样,多个单态类在一起就可以作为一个状态仓库一样向外提供服务,比如,你要论坛中的帖子计数器,每次浏览一次需要计数,单态类能否保持住这个计数,并且能synchronize的安全自动加1,如果你要把这个数字永久保存到数据库,你可以在不修改单态接口

面向对象设计模式的核心法则_javascript技巧

1. 单一职责 就一个类而言,应该仅有一个引起它变化的原因.如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会削弱或者抑制这个类完成其他职责的能力.这种耦合会导致脆弱的设计,当变化发生时,设计会遭到意想不到的破坏.软件设计真正要做的许多内容,就是发现职责并把那些职责互相分离.如果你多于一个动机去改变一个类,那么这个类就具有多于一个的职责. 2. 开放封闭 软件实体(类,模块,函数等)应该可以扩展,但是不可修改.也就是说,对于扩展是开放的,对于更改是封闭的.如此设计,面对需

.NET中的设计模式二:单件模式

设计 单件模式(Singleton)是一个非常简单的模式,这是我第一个理解并且能运用的模式.有时候模式的复杂程度并不在于本身,而是由于他的应用目的.最初的时候面对一个模式经常充满了困惑,一个简单的调用为什么要搞的如此复杂?为什么要建立这么多类,只是为了打开一个文件. 通常说来学习一个模式是一个接受.认可.领会的过程.接受:了解模式的结构,了解实例的意义:认可:认可该模式在实际工程中的作用和可行性:领会:将模式应用到开发过程中. 而模式的应用目的说到底无非是为了降低模块之间在时间和空间上的耦合程度

设计模式观察-Singleton

本篇先讨论单件 Singleton,单件的目标是保证一个类型只有一个实例,那么由谁来保证实例的唯一性呢?可能的方案有: a)调用端保证. 调用端调用一个类时,他是不需要也不会去考虑这个类是否已经被实例化的.而且把这样的监管工作交给调用端是很不负责的做法. b)类型内部保证. 类型内部如何保证? 将实例创建工作放到类型内部,这样类型就可以将实例创建工作监管起来.类型可以知道内部的实例有没有被创建,甚至可以知道创建实例的工作被执行了多少次. 所以个人认为理解单件需要分为两步: 1.监管工作谁来做?实

设计模式笔记 Singleton 单例模式

单例模式大概是最直观的一种设计模式了,尽管直观却不简单. 数学与逻辑学中,singleton定义为"有且仅有一个元素的集合", 单例模式可以如下定义:"一个类有且仅有一个实例,并且自行实例化向整个系统提供". 我比较喜欢Design Patterns 一书中的描述"保证一个类仅有一个实例,并提供一个访问它的全局访问点". 单例模式的特点 1.单例类只能有一个实例 2.单例类必须自己自己创建自己的唯一实例 3.例类必须给所有其他对象提供这一实例 单

php设计模式——单例模式(Singleton)的常见应用场景

单例模式(Singleton)也叫单态模式,是设计模式中最为简单的一种模式,甚至有些模式大师都不称其为模式,称其为一种实现技巧,因为设计模式讲究对象之间的关系的抽象,而单例模式只有自己一个对象,也因此有些设计大师并把把其称为设计模式之一. 这里又不具体讲如何实现单例模式和介绍其原理(因为这方便的已经有太多的好文章介绍了),如果对单例模式不了解的可以先看下:http://terrylee.cnblogs.com/archive/2005/12/09/293509.html .当然也可以自己搜索.

解读设计模式----单例模式(Singleton Pattern)

单例模式可以保证一个类有且只有一个实例,并提供一个访问它的全局访问点.在程序设计中,有很多情况需要确保一个类只能有一个实例.从这句话可以看出,Singleton模式的核心:如何控制用户使用new对一个类的实例构造器的任意调用.如何绕过常规的构造器,提供一种机制来保证一个类只有一个实例?这应该是类设计者的责任,而不是使用者的责任. 一.单例模式意图 保证一个类有且只有一个实例,并提供一个访问它的全局访问点. 二.单例模式UML图(该图来至http://www.dofactory.com/) 三.示

在Java中应用设计模式之Singleton

基本概念 ingleton 是一种创建性模型,它用来确保只产生一个实例,并提供一个访问它的全局访问点.对一些类来说,保证只有一个实例是很重要的,比如有的时候,数据库连接或 Socket 连接要受到一定的限制,必须保持同一时间只能有一个连接的存在. 再举个例子,集合中的 set 中不能包含重复的元素,添加到set里的对象必须是唯一的,如果重复的值添加到 set,它只接受一个实例.JDK中正式运用了Singleton模式来实现 set 的这一特性,大家可以查看java.util.Collection

.NET设计模式-享元模式(Flyweight Pattern)

享元模式(Flyweight Pattern) --.NET设计模式系列之十三 Terrylee,2006年3月 摘要:面向对象的思想很好地解决了抽象性的问题,一般也不会出现性能上的问题.但是在某些情况下,对象的数量可能会太多,从而导致了运行时的代价.那么我们如何去避免大量细粒度的对象,同时又不影响客户程序使用面向对象的方式进行操作? 本文试图通过一个简单的字符处理的例子,运用重构的手段,一步步带你走进Flyweight模式,在这个过程中我们一同思考.探索.权衡,通过比较而得出好的实现方式,而不