zoukankan      html  css  js  c++  java
  • 单例模式及常见写法分析(设计模式01)

    保证一个类仅有一个实例。并提供一个该实例的全局訪问点。

    ——《设计模式》

    单例模式的概念非常easy。以下以C#语言为样例,列出常见单例写法的优缺点。

    1、简单实现

     public sealed class Singleton
        {
            static Singleton instance = null;
    
            public void Show()
            {
                Console.WriteLine(  "instance function");
            }
            private Singleton()
            {
            }
    
            public static Singleton Instance
            {
                get
                {
                    if (instance == null)
                    {
                        instance = new Singleton();
                    }
                    return instance;
                }
            }
        }
    评注:

             对于线程来说不安全
     单线程中已满足要求
    长处:
    由于实例是在 Instance 属性方法内部创建的。因此类能够使用附加功能
    直到对象要求产生一个实例才执行实例化;这样的方法称为“惰性实例化”。

    惰性实例化避免了在应用程序启动时实例化不必要的 singleton。

    2、线程的安全

    public sealed class Singleton
        {
            static Singleton instance = null;
            private static readonly object padlock = new object();
    
            private Singleton()
            {
            }
    
            public static Singleton Instance
            {
                get
                {
                    lock (padlock)
                    {
                        if (instance == null)
                        {
                            instance = new Singleton();
                        }
                    }
    
                    return instance;
                }
            }
        }


    评注:

    同一个时刻加了锁的那部分程序仅仅有一个线程能够进入
    对象实例由最先进入的那个线程创建
    后来的线程在进入时(instence == null)为假,不会再去创建对象实例
    添加了额外的开销,损失了性能


    3、双重锁定

     public sealed class Singleton
        {
            static Singleton instance = null;
            private static readonly object padlock = new object();
    
            private Singleton()
            {
            }
    
            public static Singleton Instance
            {
                get
                {
                    if (instance == null)
                    {
                        lock (padlock)
                        {
                            if (instance == null)
                            {
                                instance = new Singleton();
                            }
                        }
                    }
                    return instance;
                }
            }
        }
    评注:

    多线程安全
    线程不是每次都加锁
    同意实例化延迟到第一次訪问对象时发生


    4、静态初始化

     public sealed class Singleton
        {
            private static readonly Singleton instance = null;
            static Singleton()
            {
                instance = new Singleton();
            }
            private Singleton()
            {
            }
            public static Singleton Instance
            {
                get
                {
                    return instance;
                }
            }
        }
    评注:

    依赖公共语言执行库负责处理变量初始化
    公共静态属性为訪问实例提供了一个全局訪问点
    对实例化机制的控制权较少(.NET代为实现)
    静态初始化是在 .NET 中实现 Singleton 的首选方法

    小注:

    静态构造函数既没有訪问修饰符,C#会自己主动把他们标记为private。之所以必须标记为private。

    是为了阻止开发者写的代码调用它,对它的调用总是由CLR负责的。






    5、延迟初始化

    public sealed class Singleton
        {
            private Singleton()
            {
            }
            public static Singleton Instance
            {
                get
                {
                    return Nested.instance;
                }
            }
    
            public static void Hello()
            {
            }
    
            private class Nested
            {
                internal static readonly Singleton instance = null;
                static Nested()
                {
                    instance = new Singleton();
                }
            }
        }
    评注:

    初始化工作由Nested类的一个静态成员来完毕,这样就实现了延迟初始化。

    由于静态函数的调用时机,是在类被实例化或者静态成员被调用的时候进行调用。并且是由.net框架来调用静态构造函数来初始化静态成员变量。 所以,假设依照写法四来写。再调用Hello方法的时候,就会实例化出来Singleton实例,这不是我们想看到的。由于我们有可能仅仅是想用Hello方法,而不是别的。


    注意事项:

    1、Singleton模式中的实例构造器能够设置为protected以同意子类派生。
    2、Singleton模式一般不要支持ICloneable接口,由于这可能会导致多个对象实例,与Singleton模式的初衷违背。


    3、Singleton模式一般不要支持序列化,由于这也有可能导致多个对象实例,相同与Singleton模式的初衷违背。
    4、Singletom模式仅仅考虑到了对象创建的管理,没有考虑对象销毁的管理。就支持垃圾回收的平台和对象的开销来讲,我们一般没有必要对其销毁进行特殊的管理。


    总结:

    1、Singleton模式是限制而不是改进类的创建。
    2、理解和扩展Singleton模式的核心是“怎样控制用户使用new对一个类的构造器的随意调用”。
    3、能够非常easy的改动一个Singleton,使它有少数几个实例。这样做是同意的并且是有意义的。


    作者:jiankunking 出处:http://blog.csdn.net/jiankunking


      本文部分内容来自网络,截图部分来自《CLR.via.C#第三版》




  • 相关阅读:
    1.14 作业
    1.12作业
    1.9 作业 矩阵转置与输出九宫格
    1.8 作业
    1.7 作业 打印菱形
    1.5 作业
    1.4作业 不同的年龄,不同的问候语
    PHP语言 -- 发起流程
    PHP语言 -- 新建流程
    PHP语言 -- 权限
  • 原文地址:https://www.cnblogs.com/mfmdaoyou/p/7233846.html
Copyright © 2011-2022 走看看