• 设计模式研究(二)Singleton


    上篇:设计模式研究(一)实例比较TemplateMethod与Strategy

    本篇先讨论单件 Singleton,单件的目标是保证一个类型只有一个实例,那么由谁来保证实例的唯一性呢?可能的方案有:

    a)调用端保证。
    调用端调用一个类时,他是不需要也不会去考虑这个类是否已经被实例化的。而且把这样的监管工作交给调用端是很不负责的做法。
    b)类型内部保证。

    类型内部如何保证?

    将实例创建工作放到类型内部,这样类型就可以将实例创建工作监管起来。类型可以知道内部的实例有没有被创建,甚至可以知道创建实例的工作被执行了多少次。

    所以个人认为理解单件需要分为两步:

    1、 监管工作谁来做?实例的监管工作需要类型自己去做。

    2、 监管工作如何做?类型如何保证实例唯一就是技术实现问题了,可以看到的版本有 线程安全的、双重锁定的、延迟初始化的等。

    下面使用伪代码逐步分析实例化工作放到类型内部的做法。

     调用我,实例我给你

        class Singleton
        {
            Singleton Instance 
    = null;
            
    // 实例化类型 Singleton
            Singleton GetInstance()
            {
                Instance 
    = new Singleton();
                
    return Instance;
            }

        }

    你只管调用,我保证唯一

        class Singleton
        {
            Singleton Instance 
    = null;
            
    //实例化类型 Singleton
            Singleton GetInstance()
            {
                Instance 
    = new Singleton();
                
    return Instance;
            }
            
    // 实例化类型 Singleton,实例化时判断类型有没有被创建过,这样就保证了实例的唯一
            Singleton GetInstance()
            {
                
    if (Instance == null)
                {
                    Instance 
    = new Singleton();
                }
                
    return Instance;
            }

        }

    你们都可以调用,我需要统计调用次数

    class Singleton
        {
            Singleton Instance 
    = null;
            
    public int Count { getset; }
            
    //实例化类型 Singleton
            Singleton GetInstance()
            {
                Instance 
    = new Singleton();
                
    return Instance;
            }
            
    // 实例化类型 Singleton,实例化时判断类型有没有被创建过,这样就保证了实例的唯一
            Singleton GetInstance()
            {
                
    if (Instance == null)
                {
                    Instance 
    = new Singleton();
                }
                
    return Instance;
            }
            
    // 实例化类型 Singleton,并且加入一个计数器,这样能知道实例化工作被执行了多少次
            Singleton GetInstance()
            {
                Count
    ++;
                
    if (Instance == null)
                {
                    Instance 
    = new Singleton();
                }
                
    return Instance;
            }

        }

    想使用实例?请出示合法证件

    class Singleton
        {
            Singleton Instance 
    = null;
            
    public int Count { getset; }
            
    //实例化类型 Singleton
            Singleton GetInstance()
            {
                Instance 
    = new Singleton();
                
    return Instance;
            }
            
    // 实例化类型 Singleton,实例化时判断类型有没有被创建过,这样就保证了实例的唯一
            Singleton GetInstance()
            {
                
    if (Instance == null)
                {
                    Instance 
    = new Singleton();
                }
                
    return Instance;
            }
            
    // 实例化类型 Singleton,并且加入一个计数器,这样能知道实例化工作被执行了多少次
            Singleton GetInstance()
            {
                Count
    ++;
                
    if (Instance == null)
                {
                    Instance 
    = new Singleton();
                }
                
    return Instance;
            }
            
    // 实例化类型 Singleton,并且接收一个合法的授权,这样可以知道每个授权方的调用次数,使用频率
            Singleton GetInstance(string caller)
            {
                
    //Check 调用方合法性验证
                if (Check(caller))
                {
                    CallerCount(caller);
                    
    if (Instance == null)
                    {
                        Instance 
    = new Singleton();
                    }
                    
    return Instance;
                }
                
    else
                    
    return null;
            }
            
    //记录调用方调用次数
            public void CallerCount(string caller)
            {
                
    //caller Count++
            }
            
    public bool Check(string caller)
            {
                
    return true;
            }
        }


     欢迎一起讨论!

     --------------------------补充-------------------------------

    我把几种流行的 Singleton 写法发出来,省的大家再去查资料。

      public sealed class MySingleton
        {
            
    static MySingleton instance = null;
            MySingleton() { }
            
    //简单写法
            public static  MySingleton Istance 
            {
                
    get
                {
                    
    if (instance == null)
                    {
                        instance 
    = new MySingleton();
                    }
                    
    return instance;
                }
            }
            
    //线程安全
            static readonly object obj = new object();
            
    public static MySingleton SafeInstance
            {
                
    get
                {
                    
    lock (obj)
                    {
                        
    if (instance == null)
                            instance 
    = new MySingleton();
                        
    return instance;
                    }
                }
            }
            
    //双重锁定 节约开销
            public static MySingleton LockInstance
            {
                
    get
                {
                    
    if (instance == null)
                    {
                        
    lock (obj)
                        {
                            
    if (instance == null)
                                instance 
    = new MySingleton();
                        }
                    }
                    
    return instance;
                }
            }
            
    //静态初始化
            static MySingleton() { }
            
    static readonly MySingleton staticinstance = new MySingleton();
            
    public static MySingleton StaticInstance
            {
                
    get
                {
                    
    return staticinstance;
                }
            }
            
    //延迟初始化
            public static MySingleton lazyInstance
            {
                
    get
                {
                    
    return Lazy.staticinstance;
                }
            }
            
    class Lazy
            {
                
    internal static readonly MySingleton staticinstance = new MySingleton();
                
    static Lazy() { }
            }
        }


    作者:青羽
  • 相关阅读:
    复制表结构及数据
    mysql 字段名是关键字 报错
    mysql 截取字符串
    《官方资料》 例如:string 函数 、分组函数
    mysql event 入门
    Spring国际化
    Python学习记录
    精选股文
    为VS定制一个自己的代码生成器
    房产常识
  • 原文地址:https://www.cnblogs.com/tenghoo/p/tenghoo_Singleton.html
Copyright © 2020-2023  润新知