C++单例模式、工厂模式、观察者模式等的实现和应用场景。

设计模式是软件开发中常用的解决方案,它们提供了一些经过验证的方法来解决常见的设计问题。以下是单例模式、工厂模式和观察者模式在C++中的实现和应用场景的详细讲解。

1. 单例模式(Singleton Pattern)

概念

单例模式确保一个类只有一个实例,并提供一个全局访问点来访问这个实例。这对于管理全局状态、配置对象、日志记录对象等非常有用。

实现

在C++中实现单例模式通常涉及以下步骤:

  • 私有化构造函数、复制构造函数和赋值操作符,防止外部创建对象。
  • 提供一个静态方法来获取类的唯一实例。
    #include <iostream>
    #include <mutex>
    
    class Singleton {
    public:
        // 获取单例实例的静态方法
        static Singleton& getInstance() {
            static Singleton instance; // 使用静态局部变量确保唯一实例
            return instance;
        }
    
        // 示例方法
        void showMessage() {
            std::cout << "Hello from Singleton!" << std::endl;
        }
    
        // 删除复制构造函数和赋值操作符,防止复制
        Singleton(const Singleton&) = delete;
        Singleton& operator=(const Singleton&) = delete;
    
    private:
        // 私有构造函数,防止外部实例化
        Singleton() {
            std::cout << "Singleton Constructor Called" << std::endl;
        }
    };
    
    int main() {
        Singleton& instance1 = Singleton::getInstance();
        Singleton& instance2 = Singleton::getInstance();
    
        instance1.showMessage();
    
        if (&instance1 == &instance2) {
            std::cout << "Both instances are the same." << std::endl;
        }
    
        return 0;
    }
    

应用场景
  • 配置管理: 全局共享的配置管理器。
  • 日志系统: 统一的日志记录类,用于在整个应用程序中收集日志。
  • 资源管理: 控制对全局共享资源的唯一访问点,比如数据库连接池。

2. 工厂模式(Factory Pattern)

概念

工厂模式通过定义一个创建对象的接口,让子类决定实例化哪个类。工厂模式使一个类的实例化过程延迟到子类。

工厂模式包括以下几种常见变体:

  • 简单工厂模式(Simple Factory Pattern): 提供一个方法来创建对象。
  • 工厂方法模式(Factory Method Pattern): 定义一个接口来创建对象,由子类来决定实例化哪个具体的类。
  • 抽象工厂模式(Abstract Factory Pattern): 提供一个接口来创建一系列相关或依赖的对象,而不需要指定它们的具体类。
实现

下面是一个简单工厂模式的示例,用于创建不同类型的产品对象:

#include <iostream>
#include <memory>

// 产品基类
class Product {
public:
    virtual void show() = 0;
    virtual ~Product() = default;
};

// 具体产品类 A
class ConcreteProductA : public Product {
public:
    void show() override {
        std::cout << "ConcreteProductA created." << std::endl;
    }
};

// 具体产品类 B
class ConcreteProductB : public Product {
public:
    void show() override {
        std::cout << "ConcreteProductB created." << std::endl;
    }
};

// 简单工厂类
class SimpleFactory {
public:
    enum ProductType { PRODUCT_A, PRODUCT_B };

    static std::unique_ptr<Product> createProduct(ProductType type) {
        switch (type) {
            case PRODUCT_A:
                return std::make_unique<ConcreteProductA>();
            case PRODUCT_B:
                return std::make_unique<ConcreteProductB>();
            default:
                return nullptr;
        }
    }
};

int main() {
    auto productA = SimpleFactory::createProduct(SimpleFactory::PRODUCT_A);
    auto productB = SimpleFactory::createProduct(SimpleFactory::PRODUCT_B);

    productA->show();
    productB->show();

    return 0;
}
应用场景
  • 对象创建逻辑复杂: 当对象创建的逻辑非常复杂且可能涉及多个步骤时,工厂模式可以隐藏这些细节。
  • 解耦: 工厂模式可以将客户端与具体的类解耦,使得更容易扩展和维护。
  • 动态实例化: 根据运行时条件动态决定创建哪个类的实例。

3. 观察者模式(Observer Pattern)

概念

观察者模式定义了一种一对多的依赖关系,当一个对象的状态发生变化时,所有依赖于它的对象都会自动收到通知并更新。它用于实现对象间的解耦通信。

实现

在C++中,实现观察者模式通常涉及以下组件:

  • 主体(Subject): 被观察的对象,它维护一个观察者列表,并在状态改变时通知它们。
  • 观察者(Observer): 接受通知并作出相应反应的对象。
    #include <iostream>
    #include <vector>
    #include <memory>
    
    // 观察者接口
    class Observer {
    public:
        virtual void update(int state) = 0;
        virtual ~Observer() = default;
    };
    
    // 具体观察者
    class ConcreteObserver : public Observer {
    public:
        void update(int state) override {
            std::cout << "Observer updated with state: " << state << std::endl;
        }
    };
    
    // 主体(被观察者)
    class Subject {
    public:
        void addObserver(std::shared_ptr<Observer> observer) {
            observers.push_back(observer);
        }
    
        void setState(int newState) {
            state = newState;
            notifyObservers();
        }
    
    private:
        void notifyObservers() {
            for (const auto& observer : observers) {
                observer->update(state);
            }
        }
    
        std::vector<std::shared_ptr<Observer>> observers;
        int state;
    };
    
    int main() {
        std::shared_ptr<Observer> observer1 = std::make_shared<ConcreteObserver>();
        std::shared_ptr<Observer> observer2 = std::make_shared<ConcreteObserver>();
    
        Subject subject;
        subject.addObserver(observer1);
        subject.addObserver(observer2);
    
        subject.setState(10);
        subject.setState(20);
    
        return 0;
    }
    
    应用场景
  • 事件处理系统: 当事件发生时,通知所有感兴趣的对象(例如 GUI 框架中的事件处理)。
  • 订阅发布系统: 允许多个对象订阅一个主题,当主题有更新时,所有订阅者都会收到通知。
  • 模型-视图-控制器(MVC)架构: 在MVC中,视图对象可以观察模型对象,当模型数据改变时,视图会自动更新。这些模式都是非常实用的工具,可以帮助开发者编写更灵活、可扩展和可维护的代码。

总结

单例模式用于确保一个类只有一个实例,适合管理全局状态或资源。

工厂模式用于创建对象,适合对象创建逻辑复杂或需要解耦的场景。

这些模式都是非常实用的工具,可以帮助开发者编写更灵活、可扩展和可维护的代码。

观察者模式用于在对象之间建立一对多的依赖关系,适合事件通知或数据同步的场景。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/772783.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CocoaPodsCmake

https://juejin.cn/post/7257048145233838141?searchId20240531171431E5868B41DC7B7016CCBA https://guides.cocoapods.org CocoaPods CocoaPods的作用 帮助程序员通过命令管理第三方库及更新&#xff0c;以达到扩展项目的目的。 CocoaPods的使用 在已有的工程目录下新增…

JAVA:文件防重设计指南

1、简述 在现代应用程序中&#xff0c;处理文件上传是一个常见的需求。为了保证文件存储的高效性和一致性&#xff0c;避免重复存储相同的文件是一个重要的优化点。本文将介绍一种基于哈希值的文件防重设计&#xff0c;并详细列出实现步骤。 2、设计原理 文件防重的基本思路…

智能家居安防系统教学解决方案

前言 随着科技的不断进步和智能家居概念的深入人心&#xff0c;智能家居安防系统作为智能家居领域的重要组成部分&#xff0c;其重要性日益凸显。智能家居安防系统不仅能够提供环境和人员的监测功能&#xff0c;还能够采取措施降低或避免人员伤亡及财产损失。因此&#xff0c;…

leetcode216.组合总和III、40.组合总和II、39.组合总和

216.组合总和III 找出所有相加之和为 n 的 k 个数的组合&#xff0c;且满足下列条件&#xff1a; 只使用数字1到9 每个数字 最多使用一次 返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次&#xff0c;组合可以以任何顺序返回。 示例 1: 输入: k 3, n 7 输出…

百日筑基第十一天-看看SpringBoot

百日筑基第十一天-看看SpringBoot 创建项目 Spring 官方提供了 Spring Initializr 的方式来创建 Spring Boot 项目。网址如下&#xff1a; https://start.spring.io/ 打开后的界面如下&#xff1a; 可以将 Spring Initializr 看作是 Spring Boot 项目的初始化向导&#xff…

实训学习错误总结2

1、 "timestamp": "2024-07-04T08:43:07.15400:00", "status": 405, "error": "Method Not Allowed", "path": "/wuzi/insert" 简单的来说就是使用的方法与注释不匹配。 规定的是&#xff1a;Get&a…

第20章 Mac+VSCode配置C++环境

1. 下载VSCode VSCode下载地址在mac终端里输入xcode- select --install命令,根据提示安装xcode工具。2. 安装插件(4个) 打开VScode,点击应用右侧菜单栏 C/C++(必装) Code Runner(必装) CodeLLDB(代码调试),不安装这个插件程序调试时,无法在vscode自带的终端里输入参…

redis学习(002 安装redis和客户端)

黑马程序员Redis入门到实战教程&#xff0c;深度透析redis底层原理redis分布式锁企业解决方案黑马点评实战项目 总时长 42:48:00 共175P 此文章包含第5p-第p7的内容 文章目录 安装redis启动启动方式1&#xff1a;可执行文件启动启动方式2 基于配置文件启动修改redis配置文件 …

第四十七章 解决 IRIS 中的 SOAP 问题 - Web 网关中的 HTTP 跟踪

文章目录 第四十七章 解决 IRIS 中的 SOAP 问题 - Web 网关中的 HTTP 跟踪Web 网关中的 HTTP 跟踪第三方追踪工具 第四十七章 解决 IRIS 中的 SOAP 问题 - Web 网关中的 HTTP 跟踪 Web 网关中的 HTTP 跟踪 Web 网关管理页面可让跟踪 HTTP 请求和响应。请参阅使用 HTTP 跟踪工…

项目管理所需资料【资料分享】

项目管理基础知识 项目管理可分为五大过程组&#xff08;启动、规划执行、监控、收尾&#xff09;十大知识领域&#xff0c;其中包含49个子过程 项目十大知识领域分为&#xff1a;项目整合管理、项目范围管理、项目进度管理、项目成本管理、项目质量管理、项目资源管理、项目…

【BUUCTF-PWN】11-ciscn_2019_c_1

64位&#xff0c;开启了NX保护 执行效果如下&#xff1a; main函数 encrypt()函数 gets()函数存在栈溢出&#xff0c;但是中间部分代码会对传入的字符串做加密处理 中间的部分是对字符串进行处理&#xff0c;strlen的作用是得知字符串的长度&#xff0c;但是遇到’\0‘就…

C#委托事件的实现

1、事件 在C#中事件是一种特殊的委托类型&#xff0c;用于在对象之间提供一种基于观察者模式的通知机制。 1.1、事件的发送方定义了一个委托&#xff0c;委托类型的声明包含了事件的签名&#xff0c;即事件处理器方法的签名。 1.2、事件的订阅者可以通过运算符来注册事件处理器…

欧拉筛法与埃氏拉筛

如果我们想知道从零到一个数有哪些质数&#xff0c;我们首先会想到运用枚举法&#xff0c;将小于这个数的每个数都相乘一遍&#xff0c;这样的做法会大大降低我们程序的质数&#xff0c;增加时间&#xff0c;事实上&#xff0c;在我们之前就有许多人尝试运用另外的思维&#xf…

2pc 3pc

2pc&3pc问题 本质&#xff1a; 2pcTM超时机制 3pc加入事务询问机制RM超时机制 事务询问机制&#xff1a;减少阻塞 RM超时机制&#xff1a;避免死锁 2pc 3pc 参考&#xff1a; https://juejin.im/post/5aa3c7736fb9a028bb189bca#heading-1 https://blog.csdn.net/xj1…

【笔记】在window上连接虚拟机中的redis

愚昧啊 困扰了我近两天的问题居然是因为是java代码写错地方了 在虚拟机中进入redis.conf文件 vim redis.conf /bind --斜杠搜索关键词 将值设置为 bind 0.0.0.0 保存 退出:wq 回到java中 添加redis依赖 刷新maven 就是在这一步出问题……………………………………自己在蓝…

RK3568平台(opencv篇)ubuntu18.04上安装opencv环境

一.什么是 OpenCV-Python OpenCV-Python 是一个 Python 绑定库&#xff0c;旨在解决计算机视觉问题。   Python 是一种由 Guido van Rossum 开发的通用编程语言&#xff0c;它很快就变得非常流行&#xff0c;主要是 因为它的简单性和代码可读性。它使程序员能够用更少的代码行…

【踩坑】修复报错Cannot find DGL libdgl_sparse_pytorch_2.2.0.so

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;欢迎[点赞、收藏、关注]哦~ 目录 错误复现 原因分析 解决方法 错误复现 import dgldataset dgl.data.CoraGraphDataset() graph dataset[0] graph.adjacency_matrix() 原因分…

MySQL第二次作业

一、数据库 1、登陆数据库 2、创建数据库zoo 3、修改数据库zoo字符集为gbk 4、选择当前数据库为zoo 5、查看创建数据库zoo信息 6、删除数据库zoo 二、创建表 1、创建一个名称为db_system的数据库 2、在该数据库下创建两张表&#xff0c;具体要求如下 员工表 user 字段 类型 约…

阿里模型调用体验

引言 随着人工智能技术的飞速发展&#xff0c;大型模型已成为推动技术进步的关键因素之一。阿里大模型作为国内领先的人工智能技术之一&#xff0c;其在多个领域的应用展示了强大的潜力。本文将通过调用案例&#xff0c;简单解析阿里大模型在特定场景中的应用及其效果。 1.导…

面试知识储备-SpringCloud

1.为什么要出现springcloud? 单体架构 定义:传统的项目所有功能打成一个jar包就能直接部署,所有功能糅合到一起,非常简单 缺点:大公司项目某些功能的并发量大,会占用大量的资源,影响其他功能的正常运行(比如非常重要的交易功能) 微服务架构 定义:将各个功能拆分为独立项目…
最新文章