zoukankan      html  css  js  c++  java
  • 设计模式之单例模式(C#)

    本文来自于本人个人微信公众号,欢迎关注本人微信公众号,二维码附在文章末尾~~~

    一直都特别羡慕能写文章的人,但是由于本人比较懒再加上写文章功底实在是just so so,所以就一搁再搁,最近突然觉得自己的技术能力好像很长时间都停滞不前,有一种隐隐的危机感,所以不得不逼自己一把。我写文章的目的主要是对自己一个学习的总结,情感的抒发以及生活的记录,顺便提高自己的文字功底与技术能力,当然如果能帮助到别人那自然是极好的,哈哈!!!

    下面就开始我的第一篇微信公众文章内容啦,文章中涉及代码的部分以C#为主。

    1. 单例模式的特点

      顾名思义,单例类只能生成一个实例,且我们必须把单例类的构造函数设为私有函数以禁止他人创建实例,即,单例类只能自己创建自己的唯一实例,其他所有对象都使用这个实例。

    2. 单例模式的结构

    3. 下面通过几种不同的解法做对比来更深入的了解单例模式

       解法1:只适用于单线程环境的解法

    解法1中Singleton的静态属性Instance中只有instance为null时才创建一个实例以避免重复创建,同时我们把构造函数定义为私有函数,这样确保只创建一个实例。

    缺点:只满足单线程,多线程下会有问题,如两个线程同时运行到判断instance是否为null的if语句,并且instance的确没有创建时,那么两个线程都会创建一个实例,此时解法一中的Singleton就不满足单例模式了

     解法2:适用于多线程,但效率不高

    解法2中通过添加同步锁解决了多线程环境下的单例模式,由于在一个时刻只有一个线程能得到同步锁,当第一个线程加上锁时,第二个线程只能等待,当第一个线程发现实例没有创建时,它创建一个实例,接着第一个线程释放同步锁,此时第二个线程可以加上同步锁运行代码,但是此时实例已经被创建,第二个实例就不会再创建实例了,这样保证在多线程下只能创建一个实例

    缺点:在每次通过属性Instance得到Singleton的实例都会试图加上一个同步锁,而加锁是一个非常耗时的操作,在非必要情况下要避免

      解法3:加同步锁前后两次判断实例是否已存在

    解法3中Singleton2中只有当instance为null即没有创建时需要加锁操作,当instance已经创建出来之后则无需加锁,因为只在第一次的时候instance为null,所以只在第一次试图创建实例的时候需要加锁,这样比解法2中的效率就高出很多。

    缺点:解法3中用加锁机制来确保在多线程环境下只创建一个实例,并且用两个if来判断来提高效率,这样的代码实现起来比较容易出错。

    解法4:利用静态构造函数

    解法4是比较推荐的解法,代码非常简洁,我们在初始化静态变量instance的时候创建一个实例,由于C#在调用静态构造函数时初始化静态变量,.NET运行时能够确保只调用一次静态构造函数,这样能保证只初始化一次instance。

     缺点:.NET第一次运行使用Singleton3时会自动调用该类型的静态构造函数,所以instance不是在第一次调用Singleton.instance被创建,而是在第一次用到Singleton3的时候被创建,会导致在单例模式中过早的创建实例,从而降低内存的使用效率。

    解法5:实现按需创建实例

    解法5中我们在内部定义了一个私有类型Nested,当第一次用到这个嵌套类型的时候,会调用静态构造函数创建Singleton4的instance实例。类型Nested只在属性Singleton4.instance中被用到,由于其私有属性他人无法使用Nested类型,因此当我们第一次试图通过属性Singleton4.instance得到Singleton4的实例时,会自动调用Nested的静态构造函数创建instance。如果我们不调用instance,那么就不会触发.NET运行时调用Nested,也不好创建实例,这样就真正做到了按需创建。

    综上五种解法,推荐解法4和解法5,单例模式是面试中的"常客",是设计模式中最简单的,看完了这篇文章是不是发现so easy 呐,好啦,今天就写到这儿,这就是我的第一篇微信公众号文章啦,欢迎吐槽,我已经做好了在吐槽中成长的准备啦~~~~~~~~

    特别声明:

    本文内容参考于书籍《剑指Offer-名企面试官精讲典型编程题》何海涛(著)

    欢迎关注本人个人微信公众号

  • 相关阅读:
    由 基本数据型态转换成 String/ 由 String 转换成 数字的基本数据型态
    屏幕适配(UGUI)非UI
    转载 Unity Text 插入超链接
    File类的使用
    抽奖
    竖倾斜ScrollView
    本地资源_Asset
    小型自动朝向转盘
    简易C# socket
    Lua class
  • 原文地址:https://www.cnblogs.com/yixuanhan/p/6844108.html
Copyright © 2011-2022 走看看