设计模式学习每天一个——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.

转载于:https://www.cnblogs.com/windy86/p/3972392.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值