【设计模式】单例模式

单例模式(Singleton Pattern)

概念:

· 确保一个类只有一个实例,并提供一个全局访问点来获取该实例;

· 限制类实例的数量为 1

· 提供一个静态方法来获取唯一实例;

UML结构:

复制代码
        Client
           |
        Singleton
           |
    -----------------
    | -instance     |
    | +GetInstance()|
    -----------------

代码示例:

cs 复制代码
/// <summary>
/// 单例模式(懒汉式)
/// </summary>
public class SingletonMono1
{
    private static readonly object instanceLocked = new();
    private static SingletonMono1 _instance;
    public static SingletonMono1 Instance
    {
        get
        {
            if (_instance == null)
            {
                lock (instanceLocked)
                {
                    if (_instance == null)
                    {
                        _instance = new();
                    }
                }
            }

            return _instance;
        }
    }

    // 私有化构造函数(默认为public)
    private SingletonMono1() { }
}

/// <summary>
/// 单例模式(饿汉式)
/// </summary>
public class SingletonMono2
{
    private static SingletonMono2 _instance = new SingletonMono2();
    public static SingletonMono2 Instance => _instance;

    // 私有化构造函数(默认为public)
    private SingletonMono2() { }
}

特点:
优点:

· 唯一实例 :全局只有一个对象,避免资源浪费;

· 全局访问点 :提供统一的入口访问实例;

· 懒加载 :可以在第一次使用时再创建实例,节省性能;
缺点:

· 难以扩展 :单例类一般不能被继承;

· 隐藏依赖 :全局使用单例可能造成代码耦合度高;

· 多线程问题 :如果实现不当,可能在多线程环境下出现多个实例;

· 不利于测试 :因为是全局对象,可能导致单元测试难以编写(可能很多因素在同时改变着这个单例);

适用场景:

· 全局唯一资源 :某个类在系统中只需要一个实例;

· 频繁访问共享资源 :需要统一控制访问,避免重复创建;

· 需要全局配置管理 :比如配置文件、日志系统;

示例:

· 日志管理器 :整个系统中只需要一个日志对象,负责统一记录日志,避免文件句柄冲突;

· 配置类 :应用启动时读取一次配置文件,后续都用单例对象来访问配置数据;

· 线程池 :系统中只需要一个线程池来管理线程;

· 数据库连接池:避免每次都创建和销毁数据库连接,统一由单例管理连接池;

相关推荐
wdfk_prog7 小时前
嵌入式面试真题第 10 题:高优化等级下共享状态可见性、内存模型与系统级同步设计
java·linux·开发语言·面试·职场和发展·架构·c
许彰午10 小时前
95_Python内存管理与垃圾回收
开发语言·python
多加点辣也没关系10 小时前
JavaScript|第13章:原始类型的方法
开发语言·javascript·ecmascript
এ慕ོ冬℘゜10 小时前
深入理解 JavaScript 事件体系:Window、鼠标与键盘事件详解
开发语言·javascript·okhttp
chouchuang12 小时前
day-030-综合练习-笔记管理器
开发语言·笔记·python
云空13 小时前
《Three.js 3D实例大全》
开发语言·javascript·3d·three.js
techdashen13 小时前
Go 1.26 新增 `bytes.Buffer.Peek`:只看数据,不移动读取位置
开发语言·后端·golang
C137的本贾尼13 小时前
第七篇:消息队列(MQ)——就是个带存储的异步通信管道
java·开发语言·中间件
从零开始的代码生活_14 小时前
C++ list 原理与实践:双向链表、迭代器与简化实现
开发语言·c++·后端·学习·算法·链表·list
hy.z_77714 小时前
【C语言】11. 深入理解指针1
c语言·开发语言