如众所知,单件模式做为<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. .Net中的设计模式——Iterator模式

    在.Net中,我们很少有机会使用Iterator模式,因为.Net Framework已经运用Iterator模式为所有的集合对象实现了迭代器.我们在遍历集合对象时,喜欢使用C#提供的foreach语 ...

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

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

  4. 工作中的设计模式 —— 策略模式

    前言 返利网站 https://m.cpa5.cn/ 策略模式是一种行为设计模式,它能让你定义一系列算法,并将每种算法分别放入独立的类中,以使算法的对象能够相互替换. 使用场景 策略模式在工作中使用的 ...

  5. 设计模式----单件模式(c++)

    单件模式是设计模式中最简单的模式了. 定义: 确保一个类只有一个实例,并提供一个全局的访问点. 把一个类设计成自己管理的一个单独实例,同时避免其他类再自行生成实例(所以构造函数用protect或pri ...

  6. Java设计模式——单件模式

    概述 有一些对象其实我们只需要一个,比方说:线程池(threadpool).缓存(cache).对话框.处理偏好设置和注册表(registry)的对象.日志对象,充当打印机.显卡等设备的驱动程序的对象 ...

  7. HeaFirst设计模式-单件模式[单例模式](Singleton Pattern)

    深入分析单件模式 本次主要介绍的内容有 单件模式 单线程下的单件模式实现 多线程下实现单件模式出现的问题分析 JMM内存模型 多线程下的单件模式实现的三种方式 这些内容,可以从最根本理解单例模式的代码 ...

  8. C++设计模式——单件模式(singleton pattern)

    一.原理讲解 由于单件模式也称为单例模式,分为懒汉式单例模式和饿汉式单例模式,两者主要区别是类对象的返回是在编译时创建?还是调用时才创建?其中,懒汉式单例模式是在程序调用时才创建,而饿汉式单例模式是在 ...

  9. 魔兽争霸之PHP设计模式-单件模式[Singleton]

    前言:我写的关于设计模式的一系列文章.这系列的文章主要针对没接触过设计模式的,或者说接触过但还不是很明白的PHPer. 问题的提出: 可能很多人都写过类,文件操作的,数据库的-- 对于数据库的类来说有 ...

最新文章

  1. 免费申领Bio-protocol单细胞研究实验方法精选集
  2. 使用驱动器f:中的光盘之前需要将其格式化_mac虚拟光驱Daemon Tools高级功能详解—光盘刻录...
  3. 使用Docker-容器命令案例1
  4. DSB2017第一名代码尝试运行(记录自用)(五)
  5. 使用REST风格架构您需要知道的一些事
  6. java开发编写基本的结构_【自学java笔记#第五天#】Java的基本程序设计结构
  7. Linux服务器部署python项目
  8. OpenRefine数据清洗实战
  9. 硬盘的IDE、AHCI和NVMe模式区别
  10. 《实况足球10》全套数值能力解析
  11. 前端-css美化网页元素(一)字体样式,文本样式
  12. 策略模式-面向接口编程
  13. 【Mac OS】如何快速复制文件或文件夹路径
  14. 给予Java初学者的学习路线建议
  15. Springboot毕设项目股票交易模拟系统76wrijava+VUE+Mybatis+Maven+Mysql+sprnig)
  16. 疯狂Java讲义(九)
  17. iPhone5S等A7设备 任意版本降级iOS10.3.3教程(方法一)
  18. 【游戏开发教程】Unity Cinemachine快速上手,详细案例讲解(虚拟相机系统 新发出品 良心教程)
  19. 物业管理信息系统的研究与实现
  20. 联想r720自带杜比驱动下载_暑假追剧补习神器,联想M10 PLUS评测

热门文章

  1. jsp中如何运行java_从上帝视角看Java如何运行
  2. PyCharm安装mysqlclient一直提示MS Visual C++ 14 required
  3. MySQL数据库(十) 一一 数据库的导出和导入
  4. 第一章 为什么使用单元测试
  5. 构建之法读书笔记之五
  6. python:多线程
  7. 删除字符串最后一个字符的几种方法
  8. 【循序渐进学Python】1. Python基础知识
  9. echo打印彩色的用法
  10. ecshop调用指定分类(包含子分类)下所有产品的评论信息