C#设计模式04-单例模式

        昨天给大家介绍了原型模式,今天给大家介绍的是单例模式,也是最简单的一种创建型模式。

        在我们的软件系统中,有时候保持一个类只有一个实例是非常重要的。比如说,操作系统中的任务管理器,只能有一个窗口,也就是说它在系统中只能有一个实例,否则就会弹出多个任务管理器窗口。再比如说,系统中的打印机,同一时间只能执行一个打印任务,如果有多个打印机实例,那么同一时间可以打印多个任务,这会导致打印结果发生混乱。因此,软件开发中,有时候保持一个类只有一个实例是非常重要的。

        先看单例模式的定义:确保一个类只有一个实例,并提供一个全局访问点来访问这个唯一实例。

        那么如何确保一个类只有一个实例并且可以被外部访问呢?从定义上看有三点:一是一个类只能有一个实例,而是它必须自己创建这个实例(这样可以防止外部对它实例化),三是它必须提供一个全局的访问点(静态全局变量)。

        单例模式的角色非常简单,只有一个单例类

        那么该如何实现单例模式呢?请看下面的代码

namespace 单例模式
{
    public class Singleton
    {
        //第二步:提供一个全局访问点,外部通过这个访问点访问实例
        private static Singleton instance = null;
        //第一步:将构造函数声明为Private,可以防止外部对该对象进行实例化
        private Singleton() { }
        //第三步:单例类本身负责创建实例
        public static Singleton GetInstance()
        {
            if (instance == null)
                instance = new Singleton();
            return instance;
        }
    }
}
namespace 单例模式
{
    class Program
    {
        static void Main(string[] args)
        {
            Singleton s1 = Singleton.GetInstance();
            Singleton s2 = Singleton.GetInstance();
            if (s1 == s2)
            {
                Console.Write("s1和s2是同一个实例!");
            }
            else
            {
                Console.Write("s1和s2不是同一个实例!");
            }
            Console.ReadLine();
        }
    }
}
代码中单例模式的实现步骤已经写得很清楚,这里就不在作解释了。下面看看运行结果

运行结果显示s1和s2是同一个实例,说明外部对象拿到的是Singleton的同一个实例。

上面的实现方法是单例模式最简单的实现方法。

接下来来介绍两种不同实现方法的单例模式,饿汉式单例和懒汉式单例。

先来看看饿汉式单例类的代码。

namespace 单例模式
{
    
    public class Singleton 
    {
        private static Singleton instance = new Singleton();
        private Singleton() { }
        public static Singleton GetInstance()
        {
            return instance;
        }
    }
}
当类被加载的时候,静态变量instance就会被初始化,然后创建单例类的实例。

然后我们来看看懒汉式单例模式的代码,懒汉式和饿汉式的构造函数都是私有的,不同的是懒汉式单例类不会在类加载时初始化单例类,而是在调用静态工厂方法的时候实例化单例类。来看看下面的代码。

public class Singleton
    {
        private static Singleton instance = null;
        private static readonly object lockObject = new object();
        private Singleton() { }
        public static Singleton GetInstance()
        {
            //第一次判断
            if (instance == null)
            {
                //加锁,防止同一时刻多个线程同时访问,导致实例化多个对象
                lock (lockObject)
                {
                    //第二次判断
                    if (instance == null)
                    {
                        instance = new Singleton();
                    }
                }
            }
            return instance;
        }
    }
在代码中使用了Lock关键字对指定代码片段上锁,防止同一时刻多个线程同时访问单例类,最后导致系统的实例不是一个,而是多个。

代码中两次判断instance==null,是必不可少的。假如说两个线程同时通过第一次判断,第一个线程进入lock代码片段后,判断instance还是为空,就实例化。如果第二个线程进来我们不判断的话,它还会继续实例化单例类。

下一篇文章将给大家介绍创建型模式中的最后一种—-建造者模式。


       


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值