zoukankan      html  css  js  c++  java
  • 设计模式学习每天一个——Singleton模式

    单例模式的应用场景:不适宜出现多于一个实例的场景。当我们需要一个公共区域以便于其他各部分进行交流时,我们需要使用单利模式。单例模式就相当于大房间里有很多小房间,但是只有一个卫生间和厨房,众多小房间共用一个卫生间和厨房。我还看到过一个很生动的描述单利模式机制的例子。

    总结:面向对象设计时我们讲求的是封装,是低耦合高内聚。但是世界上的东西不管怎么封装,都是需要相互关联的。所以我们不仅要认识事物,更要清楚的认识事物之间的关联,处理好各个对象间的关系。

    问题:下面这个案例中,私有构造函数什么时候能被调用,公共变量Country什么时候初始化?

    public class Country
        {
            List<string> oCountries = new List<string>();
            public Country()
            {
                oCountries.Add("India");
                oCountries.Add("Nepal");
                oCountries.Add("USA");
                oCountries.Add("UK");
    
            }
            public IEnumerable<string> getCounties()
            {
                return (IEnumerable<string>) oCountries;
            }
        }
    
    
    public sealed class GlobalSingleton
        {
            // object which needs to be shared globally
            public Country Countries = new Country();
    
            // use static variable to create a single instance of the object
            static readonly GlobalSingleton INSTANCE = new GlobalSingleton();
    
            /// This is a private constructor, meaning no outsides have access.
            private GlobalSingleton() 
            { }
            
    public static GlobalSingleton Instance
            {
                get
                {
                  
                    return INSTANCE;
                }
            }       
        }

    Lazy Loading

    Memory barrier issue

    Double-Check-Locking

    Ensure a class only has one instance, and provide a global point of access to it.-[GOF]

    From http://csharpindepth.com/Articles/General/Singleton.aspx

    • A single constructor, which is private and parameterless. This prevents other classes from instantiating it (which would be a violation of the pattern). Note that it also prevents subclassing - if a singleton can be subclassed once, it can be subclassed twice, and if each of those subclasses can create an instance, the pattern is violated. The factory pattern can be used if you need a single instance of a base type, but the exact type isn't known until runtime.
    • The class is sealed. This is unnecessary, strictly speaking, due to the above point, but may help the JIT to optimise things more.
    • A static variable which holds a reference to the single created instance, if any.
    • A public static means of getting the reference to the single created instance, creating one if necessary.   

    Third version - attempted thread-safety using double-check locking

    // Bad code! Do not use!
    public sealed class Singleton
    {
        private static Singleton instance = null;
        private static readonly object padlock = new object();

        Singleton()
        {
        }

        public static Singleton Instance
        {
            get
            {
                if (instance == null)
                {
                    lock (padlock)
                    {
                        if (instance == null)
                        {
                            instance = new Singleton();
                        }
                    }
                }
                return instance;
            }
        }
    }

    This implementation attempts to be thread-safe without the necessity of taking out a lock every time. Unfortunately, there are four downsides to the pattern:

    • It doesn't work in Java. This may seem an odd thing to comment on, but it's worth knowing if you ever need the singleton pattern in Java, and C# programmers may well also be Java programmers. The Java memory model doesn't ensure that the constructor completes before the reference to the new object is assigned to instance. The Java memory model underwent a reworking for version 1.5, but double-check locking is still broken after this without a volatile variable (as in C#).
    • Without any memory barriers, it's broken in the ECMA CLI specification too. It's possible that under the .NET 2.0 memory model (which is stronger than the ECMA spec) it's safe, but I'd rather not rely on those stronger semantics, especially if there's any doubt as to the safety. Making the instance variable volatile can make it work, as would explicit memory barrier calls, although in the latter case even experts can't agree exactly which barriers are required. I tend to try to avoid situations where experts don't agree what's right and what's wrong!
    • It's easy to get wrong. The pattern needs to be pretty much exactly as above - any significant changes are likely to impact either performance or correctness.
    • It still doesn't perform as well as the later implementations.
  • 相关阅读:
    python+matplotlib制作雷达图3例分析和pandas读取csv操作
    python+pygame的导弹追踪鼠标游戏设置和说明
    python+pygame制作一个可自定义的动态时钟和详解
    python+tkinter制作一个可自定义的动态时钟及详细解释,珍藏版
    教你如何用python和pygame制作一个简单的贪食蛇游戏,可自定义
    博客园的博客之美化日历
    博客园的博客美化之-增加首页音乐播放器APlayer
    博客园的博客美化之文章推荐和反对按钮、看板娘、图片放大、github链接、返回顶部小火箭
    设计模式之装饰器模式
    设计模式之状态模式
  • 原文地址:https://www.cnblogs.com/windy86/p/3972392.html
Copyright © 2011-2022 走看看