zoukankan      html  css  js  c++  java
  • 设计模式(六)—— 单例模式

    模式简介


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

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

    缺点

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

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

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

  • 相关阅读:
    LeetCode偶尔一题 —— 617. 合并二叉树
    《剑指offer》 —— 链表中倒数第k个节点
    《剑指offer》 —— 青蛙跳台阶问题
    《剑指offer》—— 二维数组中的查找
    《剑指offer》—— 替换空格
    《剑指offer》—— 合并两个排序的链表
    《剑指offer》—— 礼物的最大价值
    生成Nuget 源代码包来重用你的Asp.net MVC代码
    Pro ASP.Net Core MVC 6th 第四章
    Pro ASP.NET Core MVC 6th 第三章
  • 原文地址:https://www.cnblogs.com/Answer-Geng/p/9060356.html
Copyright © 2011-2022 走看看