单例模式用于在整个软件系统当中保持唯一实例,在 C# 当中最能够体现此概念的就是静态类,静态类的生命周期是跟随整个程序,并且在整个程序中仅保有一个实例。

不过在这里我们不再详细阐述单例模式与静态类有什么区别,如果有兴趣的话可以查看 这篇博文这篇博文

这里说一下个人的理解:

  • 单例模式可以用实现接口与继承,而静态类是无法实现的。
  • 单例模式可以方便进行 Mock 测试。
  • 单例对象可以很方便的进行替换。
  • 静态类/静态方法更多的是用于工具类方法,是无状态的。

为了保证我们的对象是全局唯一的,那么我们肯定不能够通过 new 来创建单例对象,所以我们首先要将其构造函数设为私有的,其次我们肯定要有一个 static 字段来保存我们唯一的实例化对象。

既然不能通过 new 来实例化对象,则需要提供一个全局访问点。下面我们就来看一下具体实现:

public class SingletonImplementation
{
private static SingletonImplementation m_instance;
private SingletonImplementation(){} public static SingletonImplementation GetInstance()
{
if(m_instance == null) m_instance = new SingletonImplementation();
return m_instance;
}
}

实现起来是相当简单的,这里我们将构造函数设置为私有的,然后通过 GetInstance 方法来取得对象的实例。其实这里可以改用一个静态属性来实现,更加方便。

如果考虑到线程安全的话,就需要加一个 locker 来保证访问不会重复创建对象。因为如果在多线程环境当中调用这个静态类的时候,可能在同一时间都会访问到 m_instance,这个时候 m_instance 都为空的情况下就会连续创建两次实例,这就违背了初衷。最简单的方法就是加锁,让 m_instance 在同一时间只能一个线程访问这个对象。

public class SingletonImplementation
{
private static SingletonImplementation m_instance;
private static readony object _locker = new object();
private SingletonImplementation(){} public static SingetonImplementation Instance
{
get
{
lock(_locker)
{
if(m_instance == null) m_instance = new SingetonImplementation();
} return m_instance;
}
}
}

不过这样又产生了另外一个问题,如果线程每次访问 Instance 都会对 _locker 加锁后在访问实例是否存在,这样对性能影响十分严重。这里我们可以使用 双重检查锁定模式 来实现。

双重检查锁定模式(也被称为"双重检查加锁优化","锁暗示"(Lock hint)[1])

是一种软件设计模式用来减少并发系统中竞争和同步的开销。双重检查锁定模式

首先验证锁定条件(第一次检查),只有通过锁定条件验证才真正的进行加锁逻辑

并再次验证条件(第二次检查)。

也就是说我们首先验证 m_instance 是否为空,如果为空的话再进行加锁执行逻辑,否则的话直接返回已经实例化成功的 m_instance。

public class SingetonImplementation
{
private static SingetonImplementation _instance;
private static readonly object _locker = new object();
private SingetonImplementation(){} public static SingetonImplementation Instance
{
if(_instance == null)
{
locker(_locker)
{
if(_instance == null) _instance = new SingetonImplementation();
}
} return _instance;
}
}

[C#]设计模式-单例模式-创建型模式的更多相关文章

  1. Java设计模式之创建型模式

    创建型模式分为五类:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式 一.工厂方法模式:接口-实现类.工厂类

  2. GoF的23种设计模式之创建型模式的特点和分类

    创建型模式的主要关注点是“怎样创建对象?”,它的主要特点是“将对象的创建与使用分离”.这样可以降低系统的耦合度,使用者不需要关注对象的创建细节,对象的创建由相关的工厂来完成.就像我们去商场购买商品时, ...

  3. Typescript玩转设计模式 之 创建型模式

    作者简介 joey 蚂蚁金服·数据体验技术团队 前言 我们团队的工作是用单页面应用的方式实现web工具.涉及到数万到十数万行的前端代码的管理,而且项目周期长达数年. 怎么样很好地管理好这种量级的前端代 ...

  4. 单例模式——创建型模式01

    1. 名称     单例模式(Singleton Pattern):确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类.单例模式是一种对象创建型模式. 2. 问题    ...

  5. 设计模式01 创建型模式 - 单例模式(Singleton Pattern)

    参考 [1] 设计模式之:创建型设计模式(6种) | 博客园 [2] 单例模式的八种写法比较 | 博客园 单例模式(Singleton  Pattern) 确保一个类有且仅有一个实例,并且为客户提供一 ...

  6. Python与设计模式之创建型模式及实战

    用Python学习一下设计模式,如果很枯燥的话,就强行能使用的就用一下.设计模式参考Python与设计模式-途索 1. 单例模式 保证一个类仅有一个实例,并提供一个访问它的全局访问点. import ...

  7. Python版设计模式: 创建型模式:单例模式和工厂模式家族

    一. 单例模式(Singleton) 所谓单例模式,也就是说不管什么时候都要确保只有一个对象实例存在.很多情况下,整个系统中只需要存在一个对象,所有的信息都从这个对象获取,比如系统的配置对象,或者是线 ...

  8. Java设计模式_创建型模式_单例模式

    单例模式的实现: 定义一个类,在类中定义该类的静态变量,再定一个一个获取该类的静态变量的方法. UML图:

  9. Sington单例模式(创建型模式)

    一.使用Sington单例模式的动机(Motivation) 在软件系统中,经常有一些特殊的类,必须保证它们只有一个实例,才能保证它的逻辑正确性.以及良好的效率. 大多数类用的是常规的构造器,所以往往 ...

随机推荐

  1. 跟着大神学zookeeper分布式锁实现-----来自Ruthless

    前几天分享了@Ruthless大神的Redis锁,发现和大家都学习了很多东西.因为分布式锁里面,最好的实现是zookeeper的分布式锁.所以在这里把实现方式和大家分享一下. zookeeper分布式 ...

  2. 工作流Activiti5.13学习笔记(一)

    了解工作流 1.工作流(Workflow),就是“业务过程的部分或整体在计算机应用环境下的自动化”,它主要解决的是“使在多个参与者之间按照某种预定义的规则传递文档.信息或任务的过程自动进行,从而实现某 ...

  3. Django—urls系统:urls基础

    Django的urls系统简介 Django 1.11版本 URLConf官方文档 URL配置(URLconf)就像Django 所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映 ...

  4. 201621123050 《Java程序设计》第11周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2. 书面作业 本次PTA作业题集多线程 1. 源代码阅读:多线程程序BounceThread 1.1 BallR ...

  5. ubuntu1604使用源码方式安装ruby2.5.0

    本文介绍ubutntu1604环境下源代码方式安装ruby 版本2.5.0 如果内存小于2G可以开启虚拟内存,下面的命令开启4G虚拟内存 sudo dd if=/dev/zero of=/swap b ...

  6. django + nginx + uwsgi + websocket

    最近使用django框架做了一个简单的聊天机器人demo, 开发的过程中使用了django自带的websocket模块,当使用django框架自带的wsgi服务去启动的话,没有什么问题.如果要使用uw ...

  7. zookeeper安装及环境变量设置

    下载 首先去官网下载(自行选择版本):http://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.4.11/然后执行tar -zxvf解压 对于后台安装 ...

  8. Service Worker和HTTP缓存

    很多人,包括我自己,初看Service Worker多一个Cache Storage的时候,就感觉跟HTTP长缓存没什么区别. 例如大家讲的最多的Service Worker能让网页离线使用,但熟悉H ...

  9. Code::Blocks出现64-Bit mode not compled in解决方法

    原因是:Settings->compilter你选了Target x86 _64(64bit),选择Target x86 _32(32bit)即可 废了老半天劲才找到原因,希望能让朋友们少走弯路

  10. Web Api 过滤器之 AuthorizationFilter 验证过滤器

    该过滤器是最先执行的过滤器,即使把它放在最后 API [MyActionFilter] [MyExceptionFilter] [MyAuthorize] public void Get() { Tr ...