当前位置: 首页 > news >正文

软件设计模式之单例模式

文章目录

  • 软件设计模式之单例模式
    • 什么是单例模式
    • 实现方式
      • 饿汉式
      • 懒汉式
      • 双重检查锁
      • 静态内部类
      • 枚举
    • 优缺点
      • 优点
      • 缺点
    • 使用场景

软件设计模式之单例模式

什么是单例模式

单例设计模式(Singleton Pattern)是一种创建型设计模式,旨在确保一个类只有一个实例,并提供一个全局访问点来访问该实例。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。
简而言之,就是全局只有一个对象实例

实现方式

单例模式的实现方式有多种,以下是几种常见的实现方式:

饿汉式

饿汉式在类加载时就创建实例,因此线程安全,但可能会浪费内存。

//饿汉模式
//核心思想:在类加载时立即初始化单例对象
class SingLeton
{public:static SingLeton& getInstance(){return _eton;}int getData(){return _data;}protected:private:int _data;private:static SingLeton _eton;SingLeton():_data(666) {std::cout << "单例对象构造" << std::endl;};~SingLeton() {};SingLeton(const SingLeton& eton) = delete;
};SingLeton SingLeton::_eton;

懒汉式

懒汉式在第一次使用时才创建实例,节省资源,但需要加锁以确保线程安全。

//懒汉模式
//核心思想:延迟初始化,仅在首次请求时创建实例
class SingLeton
{public:static SingLeton& getInstance(){static SingLeton _eton;return _eton;}int getData(){return _data;}protected:private:int _data;private:SingLeton():_data(666) {std::cout << "单例对象构造" << std::endl;};~SingLeton() {};SingLeton(const SingLeton& eton) = delete;
};

双重检查锁

双重检查锁在多线程环境下性能较好,但实现较复杂。

#include <mutex>
#include <atomic>class Singleton {
private:static std::atomic<Singleton*> instance;static std::mutex mtx;Singleton() = default;~Singleton() = default;Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;public:static Singleton* getInstance() {Singleton* tmp = instance.load(std::memory_order_acquire);if (tmp == nullptr) {std::lock_guard<std::mutex> lock(mtx);tmp = instance.load(std::memory_order_relaxed);if (tmp == nullptr) {tmp = new Singleton();instance.store(tmp, std::memory_order_release);}}return tmp;}
};// 静态成员初始化
std::atomic<Singleton*> Singleton::instance{nullptr};
std::mutex Singleton::mtx;

静态内部类

静态内部类方式既能确保线程安全,又能实现延迟加载

// Meyer's Singleton (C++11起线程安全)
class Singleton {
public:static Singleton& getInstance() {static Singleton instance;return instance;}Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;
private:Singleton() = default;~Singleton() = default;
};

枚举

class Singleton {
public:enum { INSTANCE };static Singleton& getInstance() {static Singleton instance;return instance;}void showMessage() {std::cout << "Singleton instance created" << std::endl;}private:Singleton() {}Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;
};int main() {Singleton::getInstance().showMessage();return 0;
}

优缺点

优点

  1. 资源管理:单例模式能高效管理共享资源,确保程序内仅存在单一对象实例,从而降低资源消耗和内存占用。

  2. 全局访问:该模式提供了全局访问唯一对象的便捷途径,使得程序各模块都能轻松获取和使用该实例。

  3. 线程安全:在多线程环境中,单例模式确保仅有一个线程能创建实例,有效防止竞态条件和数据不一致问题。

  4. 创建控制:通过集中管理对象创建过程,单例模式避免了程序多处随意实例化对象的情况,提升了代码的可维护性和控制性。

缺点

  1. 灵活性不足:单例模式严格限制对象实例化,在特定场景下会降低系统灵活性。若后续开发需要支持多实例,往往需要进行较大规模的代码调整。

  2. 高耦合问题:该模式将对象创建与使用紧密绑定,容易导致其他模块过度依赖单例对象,从而影响系统的可维护性和扩展性。

  3. 测试复杂度高:单元测试时,单例对象需要特殊的环境模拟,这种额外的测试准备增加了测试工作的难度。

  4. 全局状态风险:作为全局访问点,单例对象在多线程或分布式环境中可能引发并发问题,必须谨慎处理线程安全和锁机制。

  5. 扩展性受限:当需要增强或修改单例功能时,往往涉及模式重构,这不仅提高了系统复杂度,也增加了维护难度。

使用场景

单例模式适用于以下场景:

  1. 唯一序列号生成需求
  2. Web 应用计数器实现
  3. 数据库连接管理:采用单例模式实现数据库连接管理器,确保应用全局共享单一连接实例,有效减少连接创建和释放的资源消耗
  4. 配置统一管理:通过单例对象封装应用配置信息,保证系统配置一致性,消除配置冲突风险
  5. 稀缺资源管控:对文件句柄、网络连接等有限资源,运用单例模式实现统一调度与分配
  6. 集中日志管理:基于单例模式构建全局日志记录器,为系统各模块提供统一日志接口,便于日志的集中维护
  7. 应用主控入口:采用单例模式实现应用主入口,确保启动和初始化流程仅执行一次,提供标准化的程序入口

文章转载自:

http://AVgVAalf.bpmnc.cn
http://ytjrp2wV.bpmnc.cn
http://N7EH4fmh.bpmnc.cn
http://hJaHpKkH.bpmnc.cn
http://OwhmpyQS.bpmnc.cn
http://y9D8PKTC.bpmnc.cn
http://uRZsO26s.bpmnc.cn
http://TA1z7YdD.bpmnc.cn
http://SfxjsIC6.bpmnc.cn
http://qGaMF3mV.bpmnc.cn
http://CzUjOqsL.bpmnc.cn
http://g6BKG2FZ.bpmnc.cn
http://2uFVVZEA.bpmnc.cn
http://daNqLRPJ.bpmnc.cn
http://l4uiQhcG.bpmnc.cn
http://aS3dFnol.bpmnc.cn
http://7khNOdM5.bpmnc.cn
http://oyVmbyi8.bpmnc.cn
http://6s3DYCn6.bpmnc.cn
http://Zyv36clJ.bpmnc.cn
http://rONxecZm.bpmnc.cn
http://D75HRfme.bpmnc.cn
http://8jRkRSl6.bpmnc.cn
http://ZMBc53nL.bpmnc.cn
http://2RftSjdv.bpmnc.cn
http://4lZ2gDTF.bpmnc.cn
http://mGpnmFJ0.bpmnc.cn
http://JqzyKnFy.bpmnc.cn
http://c2gqZ5Xy.bpmnc.cn
http://qaZ6Cro8.bpmnc.cn
http://www.dtcms.com/a/368732.html

相关文章:

  • 小迪安全v2023学习笔记(七十八讲)—— 数据库安全RedisCouchDBH2database未授权CVE
  • 【Go】P2 Golang 常量与变量
  • Leetcode—721. 账户合并【中等】
  • Go初级之十:错误处理与程序健壮性
  • Go语言的编译和运行过程
  • Golang语言设计理念
  • Golang Goroutine 与 Channel:构建高效并发程序的基石
  • Golang中的context包介绍及源码阅读
  • 【JMeter】分布式集群压测
  • GEO 搜索引擎优化系统源码搭建与定制开发,支持OEM
  • Linux学习-硬件(串口通信)
  • 【蓝桥杯选拔赛真题65】C++求个数 第十四届蓝桥杯青少年创意编程大赛 算法思维 C++编程选拔赛真题解
  • AI美颜与瘦脸技术全解析
  • Dify on DMS,快速构建开箱即用的客服对话数据质检服务
  • 数字人打断对话的逻辑
  • Claude Code成本浪费严重?80%开支可省!Token黑洞解密与三层省钱攻略
  • 基于STM32的交通灯设计—紧急模式、可调时间
  • (未完待续...)如何编写一个用于构建python web项目镜像的dockerfile文件
  • OpenResty 和 Nginx 到底有啥区别?你真的了解吗!
  • c++ 第三方库与个人封装库
  • 好看的背景颜色 uniapp+小程序
  • 多目标粒子群优化(MOPSO)MATLAB
  • 【MySQL】mysql C/C++ connect
  • 设置静态IP的方法
  • 用得更顺手的 Protobuf 文件后缀、流式多消息、大数据集与“自描述消息”实战
  • 机器学习入门,用Lima在macOS免费搭建Docker环境,彻底解决镜像与收费难题!
  • 从碎片化到一体化:Java分布式缓存的“三级跳”实战
  • 深入剖析RocketMQ分布式消息架构:从入门到精通的技术全景解析
  • 通过API接口管理企业微信通讯录案例
  • 飞算JavaAI炫技赛:电商系统开发全流程实战解析