zoukankan      html  css  js  c++  java
  • 【.Net边角料系列】1-单例模式(我真不是你想的那样)

    • 什么事边角料

    边角料就是你编程的时候,很少能够用上,或者说你压根就不知道得东西,我就称这些东西为边角料。这个叫.net边角料可能有点大,其实这个系列是纯粹的C#边角料系列。

    为什么写.net边角料呢,因为.net coder越来越少了,所以边角的东西,知道的人也越来越少,虽然价值不大,但是要抱着抛砖引玉的思想,把更多的人留在.net上,助力.net core红红火火大发展——之后我好转其他语言。就是这种拉一个人下水是一个,俩个人下水赚一个的精神支持着我,希望我能把.net边角料系列写完。我不是代码的生产者,只是代码的搬运工,所以对于边角料出现的代码如果有开源代码地址,我一定会将开源代码位置附上,以供下水者沉迷其中,不能自拔。

    • 边角料的单例模式

    如果说单例模式是边角料,估计我会挨喷,基本每次面试都可能被问到,而且不懂单例模式,好意思说自己是一个.net程序员吗?所以咱们这谈的不是传统的单例模式,更不会谈什么线程安全性,以及懒加载、惰性加载的问题。

    不过也得问一句,单例模式符合设计模式的六大原则吗?至少单一职责原则,它不符合。它既要保证自己单例又要保证自己原有意义。设计模式上没有什么是拆分办不到的,如果办不到,那就再拆分一次。

    所以下面我们正式介绍我们的边角料——泛型单例

    • 源码及地址

    没有什么比源码更有说服力了,首先上源码地址:nopCommerce(https://github.com/nopSolutions/nopCommerce)这个是大名鼎鼎的nopCommerce,具体它有多牛,自行百度,反正我也不知道。类文件叫做:Singleton.cs

     

     1    public class Singleton<T> : Singleton
     2     {
     3         static T instance;
     4         public static T Instance
     5         {
     6             get { return instance; }
     7             set
     8             {
     9                 instance = value;
    10                 AllSingletons[typeof(T)] = value;
    11             }
    12         }
    13     }
    14 
    15     public class SingletonList<T> : Singleton<IList<T>>
    16     {
    17         static SingletonList()
    18         {
    19             Singleton<IList<T>>.Instance = new List<T>();
    20         }
    21         public new static IList<T> Instance
    22         {
    23             get { return Singleton<IList<T>>.Instance; }
    24         }
    25     }
    26 
    27     public class SingletonDictionary<TKey, TValue> : Singleton<IDictionary<TKey, TValue>>
    28     {
    29         static SingletonDictionary()
    30         {
    31             Singleton<Dictionary<TKey, TValue>>.Instance = new Dictionary<TKey, TValue>();
    32         }
    33 
    34         public new static IDictionary<TKey, TValue> Instance
    35         {
    36             get { return Singleton<Dictionary<TKey, TValue>>.Instance; }
    37         }
    38     }
    39 
    40 
    41     public class Singleton
    42     {
    43         static Singleton()
    44         {
    45             allSingletons = new Dictionary<Type, object>();
    46         }
    47 
    48         static readonly IDictionary<Type, object> allSingletons;
    49 
    50         public static IDictionary<Type, object> AllSingletons
    51         {
    52             get { return allSingletons; }
    53         }
    54     }
    •  代码分析

    单例模式就是设计模式最最简单的了,泛型单例也是简单到令人发指。代码分析有什么说的呢,不过为了凑篇幅,强说两句吧。

    1.这里面一共有四个类:Singleton、Singleton<T>、SingletonList<T>、SingletonDictionary<TKey, TValue>。继承关系是Singleton<T>集成自Singleton,而SingletonList<T>、SingletonDictionary<TKey, TValue>继承自Singleton<T>.

    对于不熟悉泛型的同学来说,我可以拍胸脯的告诉你,泛型类可以继承自非泛型类,非泛型类可以继承自泛型类,只要你想没啥不可以的。

    2.对于这四个类,所有内容都是静态的——构造函数、字段、属性。对于静态构造函数,这个和普通构造函数不同的地方有三:首先它只用于初始化静态变量,其次静态构造函数不供其他类调用(所以不能用public、private修饰),只够clr初始化的时候调用。最后静态构造函数不能有参数列表,因为没人能给它传参。

    3.对于泛型来说,List<int>和List<string>是俩个完全不同的类,所以尽管SingletonList<T>只有一个静态变量,但是对于已经非泛化(具体类型代入后)的各个类型,都有自己的静态变量,所以每个T类型都对应SingletonList<T>的Instance属性,所以泛型类能够保证每个实例都能是全局唯一——也就是单例模式。

    4.对于Singleton非泛型类,他唯一的作用就是提供一个集合,供其他对象检索,哪些类型已经被泛型单例类缓存了。这完全不是必须的。但是他给我们提了一个醒:对于非泛型类每个类单独所有的静态变量,要放到泛型类的父类中。换句话说,就是泛型类出现静态变量要慎重,是不是要放到父类中。

    • 实用的代码

    泛型单例这段源码,虽然高大上,但是不一定符合我们的要求,所以我们有时候有实用的要求,下面就供上我简化的泛型单例源码.

        public class Singleton<T> where T:new()
        {
            static T instance=new T();
            public static T Instance
            {
                get { return instance; }
                set
                {
                    instance = value;
                }
            }
        }
    • 说到最后

    虽然泛型单例确实是边角料,但是泛型静态构造函数、以及nopCommerce绝对不是边角料。愿这些似是而非的边角料,对你有益。

  • 相关阅读:
    关于树及其各种操作
    正交矩阵与齐次矩阵
    矩阵的行列式与矩阵的逆
    线性变换
    矩阵
    向量的运算
    求两直线的交点
    微任务防抖
    二项分布
    二项式定理
  • 原文地址:https://www.cnblogs.com/watermoon2/p/8294918.html
Copyright © 2011-2022 走看看