zoukankan      html  css  js  c++  java
  • 单件模式

     一、基本概述

    单件模式:确保一个类只有一个实例,并提供一个全局访问点。

    解析如下:

      1)首先,该Singleton的构造函数必须是私有的,以保证客户程序不会通过new()操作产生一个实例,达到实现单例的目的;

      2)因为静态变量的生命周期跟整个应用程序的生命周期是一样的,所以可以定义一个私有的静态全局变量uniqueInstance来保存该类的唯一实例;

      3)必须提供一个全局函数访问获得该实例。

    如下图结构说明图:

     

    二、详细说明

    单件模式的创建,有三种方式。

    1. 使用经典方式,存在一个问题,当有多个线程同时访问时,会创建多个实例,违反了单件的本意。
    2. 使用急切方式,如果应用程序总是创建并使用单件实例,或者在创建和运行时方面的负担不太繁重,该方式可以使用。它的初始化交由静态构造函数实现,并可以在运行时编译。在这种模式下,无需自己解决线程安全性问题,CLR会给我们解决。由此可以看到这个类被加载时,会自动实例化这个类,而不用在第一次调用GetInstance()后才实例化出唯一的单例对象。
    3. 使用懒惰(双重检查加锁)方式,首先检查是否实例已经创建,如果尚未创建,“才”进行同步。这样一来,只有第一次会同步,同步中会再检查是否实例已经创建。如果性能是你关心的重点,那么这个做法可以帮你大大地减少GetInstance()的时间耗费。

    问:难道我不能创建一个类,把所有的方法和变量都定义为静态的,把类直接当作一个单件?

    答:如果你的类自给自足,而且不依赖于复杂的初始化,那么你可以这么做。但是,因为静态初始化的控制权是在CLR手上,这么做有可能导致混乱,特别是当有许多类牵涉其中的时候。这么做常常会造成一些微妙的、不容易发现的和初始化的次序有关的bug。除非你有绝对的必要使用类的单件,否则还是建议使用对象的单件,比较保险。

    问:我还是不了解为何全局变量比单件模式差。

    答:在.Net中,全局变量基本上就是对对象的静态引用。在这样的情况下使用全局变量会有一些缺点,我们已经提到了其中的一个,急切实例化VS延迟实例化。但是我们要记住这个模式的目的,确保类只有一个实例并提供全局访问。全局变量可以提供全局访问,但是不能确保只有一个实例。

    三、代码列表

    public class Singleton
    {
        //其他有用的单件数据
    
        private Singleton()
        {
        }
    
        //方式一:经典方式
        /*private static Singleton uniqueInstance;
        public static Singleton GetInstance()
        {
            if (uniqueInstance == null)
            {
                uniqueInstance = new Singleton();
            }
            return uniqueInstance;
        }*/
    
        //方式二:急切方式
        /*private static Singleton uniqueInstance = new Singleton();
        public static Singleton GetInstance()
        {
            return uniqueInstance;
        }*/
    
        //方式三:双重检查加锁方式
        /*private static Singleton uniqueInstance;
        public static Singleton GetInstance()
        {
            if (uniqueInstance == null)
            {
                lock (uniqueInstance)
                {
                    if (uniqueInstance == null)
                    {
                        uniqueInstance = new Singleton();
                    }
                }
            }
            return uniqueInstance;
            //Interlocked类为多个线程共享的变量提供原子操作。
            //CompareExchange方法比较两个对象是否相等,如果相等,则替换其中一个对象。
            //return Interlocked.CompareExchange(ref uniqueInstance, new Singleton(), null);
        }*/
    
        //其他有用的单件方法
    }
    View Code

    ---------------------------------以上内容根据《Head First 设计模式》进行整理

  • 相关阅读:
    python logging模块
    python re模块
    python xml模块
    python json,pickle,shelve模块
    python os,sys模块
    python 临时添加环境变量
    python random模块
    python time模块
    python 装饰器的简单使用
    python学习之路(二)
  • 原文地址:https://www.cnblogs.com/zwt-blog/p/6617373.html
Copyright © 2011-2022 走看看