如众所知,单件模式做为<Gof 23中设计模式>之一,其意图仅允许单件类的一个实例存在(扩展单件模式不在此文范围内),并提供全局的访问方法.UML类图如下.

http://csharpindepth.com/Articles/General/Singleton.aspx一文中列举了单件模式实现的5种方法,但诸多文章中都或多或少的遗漏一些问题:如何保证线程安全,如何保证仅有一个实例存在,如何根据业务变化扩展.

下面以C#实现单件为例,对这些问题一一说明.

  1. 1.         如何保证线程安全

在C#中可以使用static,readonly两个关键字保证单件的线程安全.static关键字修饰的静态成员在程序运行时由 .NET Framework 公共语言运行库 (CLR) 自动加载管理,这些成员是密封的,全局的,且不能被实例化。诸如此类的特点,让C#中的单件实现更加方便简洁.readonly关键字可用于保证对单件实例的引用在任何情况下不被修改.也因此与static一起保证单件的线程安全.

  1. 2.         如何保证仅有一个实例存在

在C#中,static关键字保证了对单件实例的唯一引用,隐藏构造函数保证无法通过new构造对象.但这并不能保证单件实例的唯一性.如我们可以反序列化出一个单件类型的实例,也可以通过实现克隆接口克隆一个单件的实例.

因此我们要保证单件类型不能被序列化,不能被克隆,即不能为单件类型及扩展类型添加Serializable标签和实现克隆接口或方法.

  1. 3.         如何扩展

除了在<Gof 23种设计模式>一书中提及对单件类型的扩展之外,很少有文章提到对单件类的继承扩展,甚至有的C#实现方式中直接将单件类前加上了sealed关键字来密封单件类.但是在实际项目中,业务需求的多变必然要求单件类能够被继承.Gof一书中提到了使用注册单件的方法实现单件类的继承.在C#中,我们可以使用继承类扩展单件类,使用反射来根据需求装载不同的单件子类型.

下面是具体的代码示例,示例中演示了C#中单件的一种实现方式和对单件类的继承.

using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Reflection;

namespace SingletonDemo
{
    class Program{
        static void Main(string[] args){
            try{
                Singleton s1 = Singleton.Instance;
                Console.WriteLine("This is {0}.", s1.Name);
                Singleton sc = s1.Clone();
                Console.WriteLine("This is {0}.", sc.Name);
                s1.Name = "小小";
                Console.WriteLine("This is {0}.", s1.Name);
                Console.WriteLine("This is {0}.", sc.Name);
                MySingleton s2 = MySingleton.Instance as MySingleton;
                Console.WriteLine("{0} is {1} year old.", s2.Name, s2.Age);
            }
            catch (Exception ex){
                Console.WriteLine("Error:{0}",ex.Message);
            }
        }
    }
    public class Singleton{
        public string Name = "倪大虾";
        //readonly可以保证线程安全
         static readonly Singleton instance = Create();
        static Singleton(){
        }
        protected Singleton(){
        }       
        public static Singleton Instance{
            get{
                return instance;
            }
        }
        private static Singleton Create(){
            try{
                //从外部(注册表,配置文件...)导入
                 string typeName = "SingletonDemo.MySingleton";
                Type t = Type.GetType(typeName);
                ConstructorInfo ci = t.GetConstructor(new Type[]{});
                return (Singleton)ci.Invoke(null);
            }
            catch (Exception ex){
                throw ex;
            }
        }
        /*//不能实现克隆方法
        public Singleton Clone(){
            return new Singleton();
        }*/
    }
    [Serializable]
    public class MySingleton:Singleton{
        public int Age = 28;
    }
}

NET中的设计模式---单件模式的更多相关文章

  1. [Head First设计模式]饺子馆(冬至)中的设计模式——工厂模式

    系列文章 [Head First设计模式]山西面馆中的设计模式——装饰者模式 [Head First设计模式]山西面馆中的设计模式——观察者模式 [Head First设计模式]山西面馆中的设计模式— ...

  2. [Head First设计模式]抢票中的设计模式——代理模式

    系列文章 [Head First设计模式]山西面馆中的设计模式——装饰者模式 [Head First设计模式]山西面馆中的设计模式——观察者模式 [Head First设计模式]山西面馆中的设计模式— ...

  3. [Head First设计模式]餐馆中的设计模式——命令模式

    系列文章 [Head First设计模式]山西面馆中的设计模式——装饰者模式 [Head First设计模式]山西面馆中的设计模式——观察者模式 [Head First设计模式]山西面馆中的设计模式— ...

  4. [转] Android中的设计模式-备忘录模式

    转自Android中的设计模式-备忘录模式 定义 备忘录设计模式的定义就是把对象的状态记录和管理委托给外界处理,用以维持自己的封闭性. 比较官方的定义 备忘录模式(Memento Pattern)又叫 ...

  5. 【转】Struts2的线程安全 和Struts2中的设计模式----ThreadLocal模式

    [转]Struts2的线程安全 和Struts2中的设计模式----ThreadLocal模式 博客分类: 企业应用面临的问题 java并发编程 Struts2的线程安全ThreadLocal模式St ...

  6. C#设计模式——单件模式

    一.为何需要单件模式 需求 我们开发了一个大型的项目,其中存在许多的工具类.但是其中很多的工具类我们并不是经常使用得到,甚至 一次都不会使用.但是这些工具类都是静态的类,会消耗很多的内存,即使一次都不 ...

  7. [Head First设计模式]山西面馆中的设计模式——建造者模式

    系列文章 [Head First设计模式]山西面馆中的设计模式——装饰者模式 [Head First设计模式]山西面馆中的设计模式——观察者模式 引言 将学习融入生活中,是件很happy的事情,不会感 ...

  8. C#设计模式——单件模式(Singleton Pattern)

    一.概述在软件开发过程中,我们有时候需要保证一个类仅有一个实例,比如在一个电脑用户下只能运行一个outlook实例.这时就需要用到单件模式.二.单件模式单件模式保证一个类仅有一个实例,并提供一个访问它 ...

  9. 说说设计模式~单件模式(Singleton)

    单件模式(Singleton)要求一个类有且仅有一个实例,并且提供了一个全局的访问点. 从概念上来研究一下它的实现,不考虑线程安全 1 public sealed class Singlton 2 { ...

随机推荐

  1. 原来找字也可以这样用ElseIf FindStr 手机按键精灵 跟大漠的区别

     原来找字也可以这样用ElseIf FindStr(646, 1109, 776, 1261, "公告小叉", "FFFFFF-333333", 0.9, in ...

  2. 大内核锁 BKL

    参考:http://blog.csdn.net/universus/article/details/5623971                                            ...

  3. appium的xpath定位问题及常用方法

    关于类似的帖子好像很多,但是没有找到具体能帮我解决问题的办法.还是自己深究了好久才基本知道app上面的xpath定位和web上的不同点: 先放一个图: A,先说说不用xpath的场景,一般是用于存在i ...

  4. 【python】logging

    https://docs.python.org/3/howto/logging.html import logging # create logger logger = logging.getLogg ...

  5. 【Dynamic Programming】DP算法

    http://www.hawstein.com/posts/dp-novice-to-advanced.html

  6. git clone Google的代码失败的解决方法

    git clone Google的volley代码遇Q. 想到用代理服务器就可以解决这个问题.Google了一下解决方法,记录下来,分享一下. git config:                 

  7. VB2010新特性

    1.取消了连接符(1)","之后(2)"()"前后(3)"{}"前后(4)XML(5)连接字符"&"后(6)赋值 ...

  8. AppStore应用转让流程

    可能大家都有这样的情况,给公司客户开发一个ios app的前期阶段是先发布在自己公司的开发者账户上面的,而不是直接发布在客户的开发者账号上面,这个到后期的话就有一个转让的事情,俗称“过户”. 步骤如下 ...

  9. 8 -- 深入使用Spring -- 7...3 让Spring管理控制器

    8.7.3 让Spring管理控制器 让Spring容器来管理应用中的控制器,可以充分利用Spring的IoC特性,但需要将配置Struts 2 的控制器部署在Spring容器中,因此导致配置文件冗余 ...

  10. Windows系统下运行某些程序时缺少“Msflxgrd.ocx”的解决方法

    出现这样的错误就是系统缺少相应的库文件,我们安装即可. 下载Msflxgrd.ocx,这里提供一个下载网址:https://www.ocxme.com/files/msflxgrd_ocx 64位系统 ...