• 设计模式(六)—— 单例模式


    模式简介


    保证一个类仅有一个实例,并提供一个访问它的全局访问点

    简单来说,让类自己负责保存它的唯一实例(静态私有变量),通过使用受保护的构造函数来保证没有其他实例可以被创建,并且提供一个访问该实例的公有方法(公有的静态方法),这就是单例(Singleton)模式。

    结构说明


    UML类图

    角色说明

    • Singleton

    定义一个Instance方法,允许客户访问它的唯一实例

    示例分析


    创建Singleton类

    class Singleton
    {
        //静态变量instance保存唯一实例
        private static Singleton instance;
    
        //私有化构造函数,保证唯一实例的受控访问
        private Singleton()
        {
    
        }
    
        //提供访问该实例的静态方法
        public static Singleton Instance()
        {
            if (instance == null)
            {
                instance = new Singleton();
            }
            return instance;
        }
    }
    

    客户端调用

    static void Main(string[] args)
    {
        Singleton s1 = Singleton.Instance();
        Singleton s2 = Singleton.Instance();
        Console.WriteLine(s1 == s2);
        Console.ReadLine();
    }
    

    输出结果

    懒汉式单例类与饿汉式单例类


    对于多线程的程序,调用以上示例中的Instance方法可能创建多个实例。

    懒汉式

    为了解决线程安全的问题,我们可以通过给进程加锁来处理。

    class LazySingleton
    {
        private static LazySingleton instance;
        private static readonly object syncRoot = new object();
        private LazySingleton()
        {
    
        }
    
        public static LazySingleton Instance()
        {
            if (instance == null)
            {
                lock (syncRoot)
                {
                    if (instance == null)
                    {
                        instance = new LazySingleton();
                    }
                }
            }
            return instance;
        }
    }
    

    这种在第一次引用时才会实例化的方式被称为懒汉式单例类。如同一个懒汉已经饿到不行了才去吃东西(需要使用实例时才去创建对象)。

    饿汉式

    class EagerSingleton
    {
        private static EagerSingleton instance = new EagerSingleton();
        private EagerSingleton()
        {
    
        }
        public EagerSingleton Instance()
        {
            return instance;
        }
    
    }
    

    这种使用静态初始化,在类被加载时就进行实例化的方式被称为饿汉式单例类。如同一个人被饿怕了,不管需不需要,先把吃的买好了存起来(不管是否会使用该实例,总是在类加载时就创建好实例)。

    适用场景


    • 当类只能有一个实例而且客户可以从一个公共的访问点获取它时

    • 当这个唯一实例应该是通过子类化可扩展时,并且客户应该无需修改代码就能使用一个扩展的实例时

    优缺点


    优点

    • 保证唯一实例的受控访问

    • 节约系统资源。对于一些需要频繁创建和销毁的对象,单例模式无疑可以提高系统的性能

    • 允许可变数目的实例。使用与单例控制相同的方法(if instance == null)指定对象实例的个数。

    缺点

    • 由于单例模式中没有抽象层,所以扩展起来难度较大

    • 违反了单一职责原则。因为单例类既要提供公有的访问方法,又要提供该实例的业务方法

    • 不合理地滥用单例模式可能会造成一些负面问题。如将数据库连接池对象设计成单例类,可能会导致共享连接池对象的程序过多而出现连接溢出;另外如果实例化的对象长时间不被利用,可能出现状态丢失。

  • 相关阅读:
    Linux启动或禁止SSH用户及IP的登录
    How to Setup Chroot SFTP in Linux (Allow Only SFTP, not SSH)
    vsftp被动模式启用iptables访问设置
    关于使用Element.getNodeValue()返回NULL的问题
    Quartz 有状态的JobDataMap
    log4j学习日记-写入数据库
    LeetCode 551. Student Attendance Record I (学生出勤纪录 I)
    LeetCode 680. Valid Palindrome II (验证回文字符串 Ⅱ)
    LeetCode 125. Valid Palindorme (验证回文字符串)
    LeetCode 541. Reverse String II (反转字符串 II)
  • 原文地址:https://www.cnblogs.com/Answer-Geng/p/9060356.html
Copyright © 2020-2023  润新知