设计模式C++

针对一些经典的常见的场景, 给定了一些对应的解决方案,这个就叫设计模式。

设计模式的作用:使代码的可重用性高,可读性强,灵活性好,可维护性强。

设计原则:

单一职责原则:一个类只做一方面的事。

开闭原则:以前写过的代码不能动,修改以前写的代码是非常危险的事情,我们可以在原来的基础上进行扩展,例如添加新的方法。

接口隔离原则:接口定义的功能尽量少,不要包含太多的功能。

里氏替换原则:在继承关系的代码开发中,如果需要进行功能的扩展,不要在子类中改变父类中已经实现的方法,而是通过新增方法来扩展父类的功能。

依赖倒置原则:在定义类的成员变量,参数类型,返回值类型的时候,不要写某个具体的实现类,而是尽量采用接口或者抽象类,这样后续如果我们想改,不需要改动代码,只需要增加实现类就可以了。

创建型模式:

创建型模式:用于解耦对象实例化的过程。

工厂模式:

工厂模式的思想是将对象的创建逻辑封装到一个专门的类中,客户端无需直接 new 具体类,从而降低代码耦合。

当对象创建逻辑复杂,或需要统一管理创建过程时使用工厂模式。

#include <iostream>// 抽象产品类(接口)
class Shape {
public:virtual void draw() = 0;virtual ~Shape() {} // 虚析构,确保正确释放子类对象
};// 具体产品类:圆形
class Circle : public Shape {
public:void draw() override {std::cout << "Drawing a Circle" << std::endl;}
};// 具体产品类:方形
class Square : public Shape {
public:void draw() override {std::cout << "Drawing a Square" << std::endl;}
};
简单工厂模式:

定义抽象产品类,具体产品类,工厂类,用户不必知道创建对象的细节,只需要调用工厂类(静态创建对象函数)。(针对单一产品)

违反了开闭原则,新增产品类需要修改工厂类的代码。

// 工厂类
class ShapeFactory {
public:// 根据类型创建对象(静态方法)static Shape* createShape(const std::string& type) {if (type == "Circle") {return new Circle();} else if (type == "Square") {return new Square();}return nullptr; // 无效类型返回空}
};// 客户端代码
int main() {// 通过工厂创建对象Shape* circle = ShapeFactory::createShape("Circle");Shape* square = ShapeFactory::createShape("Square");circle->draw(); // 输出: Drawing a Circlesquare->draw(); // 输出: Drawing a Squaredelete circle;delete square;return 0;
}
工厂方法模式:

创建抽象工厂类,每一个产品对应一个产品工厂。

// 抽象工厂
class ShapeFactory {
public:virtual Shape* createShape() = 0;virtual ~ShapeFactory() {}
};// 圆形工厂
class CircleFactory : public ShapeFactory {
public:Shape* createShape() override {return new Circle();}
};// 方形工厂
class SquareFactory : public ShapeFactory {
public:Shape* createShape() override {return new Square();}
};// 客户端使用
ShapeFactory* factory = new CircleFactory();
Shape* shape = factory->createShape();
抽象工厂模式:

针对 多个产品族 的创建

#include <iostream>// ----------------- 抽象产品接口 -----------------
// 抽象按钮
class Button {
public:virtual void render() = 0;virtual ~Button() {}
};// 抽象复选框
class Checkbox {
public:virtual void check() = 0;virtual ~Checkbox() {}
};// ----------------- 具体产品实现 -----------------
// Windows 按钮
class WindowsButton : public Button {
public:void render() override {std::cout << "Windows 风格按钮渲染" << std::endl;}
};// Windows 复选框
class WindowsCheckbox : public Checkbox {
public:void check() override {std::cout << "Windows 复选框被勾选" << std::endl;}
};// Mac 按钮
class MacButton : public Button {
public:void render() override {std::cout << "Mac 风格按钮渲染" << std::endl;}
};// Mac 复选框
class MacCheckbox : public Checkbox {
public:void check() override {std::cout << "Mac 复选框被勾选" << std::endl;}
};// ----------------- 抽象工厂接口 -----------------
class GUIFactory {
public:virtual Button* createButton() = 0;virtual Checkbox* createCheckbox() = 0;virtual ~GUIFactory() {}
};// ----------------- 具体工厂实现 -----------------
class WindowsFactory : public GUIFactory {
public:Button* createButton() override {return new WindowsButton();}Checkbox* createCheckbox() override {return new WindowsCheckbox();}
};class MacFactory : public GUIFactory {
public:Button* createButton() override {return new MacButton();}Checkbox* createCheckbox() override {return new MacCheckbox();}
};// ----------------- 客户端代码 -----------------
int main() {// 假设根据当前系统选择工厂GUIFactory* factory;// 模拟配置:选择 Windows 或 Mac 工厂std::string os = "Windows";if (os == "Windows") {factory = new WindowsFactory();} else {factory = new MacFactory();}// 使用工厂创建一组组件Button* button = factory->createButton();Checkbox* checkbox = factory->createCheckbox();button->render();    // 输出对应系统的按钮渲染checkbox->check();   // 输出对应系统的复选框行为delete factory;delete button;delete checkbox;return 0;
}

简单工厂 vs 工厂方法 vs 抽象工厂?

  • 简单工厂:一个工厂类负责所有产品。

  • 工厂方法:每个产品对应一个工厂子类。

  • 抽象工厂:生产一个产品家族(例如不同风格的 UI 组件)。

单例模式:

单例设计模式(Singleton Pattern) 是一种创建型设计模式,用于确保一个类只有一个实例,并提供一个全局访问点来访问该实例。单例模式无法被回收,他的生命周期随进程,可以手动释放或者使用智能指针进行管理。

饿汉模式

饿汉模式:饿汉非常简单,定义静态实例,静态方法在加载到内存时就全部加载出来,缺陷是如果很大启动时就会花很长时间。

class Singleton {
private:static Singleton instance; // 静态实例Singleton() {} // 私有构造函数// 禁止拷贝构造函数和赋值操作符,防止拷贝Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;public:static Singleton* getInstance() {return &instance; // 直接返回静态实例的地址}
};// 在类外部初始化静态实例
Singleton Singleton::instance;
懒汉模式

懒汉模式:懒汉的核心思想是“延迟加载”,使用时再创建实例,使用双重检查锁确保线程安全和同步开销。

#include <mutex>class Singleton {
private:static Singleton* instance; // 静态实例指针static std::mutex mutex; // 互斥锁,用于线程同步Singleton() {} // 私有构造函数// 禁止拷贝构造函数和赋值操作符,防止拷贝Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;public:static Singleton* getInstance() {if (instance == nullptr) { // 双重检查锁定(Double-Checked Locking)std::lock_guard<std::mutex> lock(mutex); // 加锁if (instance == nullptr) { // 再次检查实例是否已创建instance = new Singleton(); // 如果未创建,则创建实例}}return instance; // 返回实例的地址}
};// 在类外部初始化静态实例指针和互斥锁
Singleton* Singleton::instance = nullptr;
std::mutex Singleton::mutex;
Meyer's Singleton

使用静态局部变量实现的单例模式。静态局部变量的初始化是线程安全的。编译器会确保静态局部变量只被初始化一次,即使多个线程同时调用 getInstance()。同时避免了资源浪费。实现简单,是现代 C++ 中推荐的单例实现方式。

class Singleton {
private:Singleton() {} // 私有构造函数Singleton(const Singleton&) = delete; // 禁止拷贝构造Singleton& operator=(const Singleton&) = delete; // 禁止赋值操作public:static Singleton& getInstance() {static Singleton instance; // 静态局部变量return instance;}void doSomething() {std::cout << "Singleton is doing something!" << std::endl;}
};
应用场景: 

线程池,内存池

结构型模式:

结构型模式:把类和对象结合在一起形成一个更大的结构。

行为型模式:

行为性模式:类和对象如何交互,划分责任和算法。

策略模式:

允许使用者根据不同的情况选择不同的策略(算法或行为)执行。

  1. 抽象策略接口(SortStrategy
    定义所有具体策略必须实现的方法(如 sort())。

  2. 具体策略类(BubbleSortQuickSort
    实现具体的算法逻辑。

  3. 上下文类(Sorter

    • 持有策略对象的引用(通过组合关系)。

    • 提供设置策略的方法(setStrategy())和执行策略的方法(executeSort())。

#include <iostream>
#include <vector>
#include <memory>// ----------------- 1. 抽象策略接口 -----------------
class SortStrategy {
public:virtual void sort(std::vector<int>& data) = 0;virtual ~SortStrategy() {} // 虚析构确保正确释放资源
};// ----------------- 2. 具体策略类 -----------------
// 冒泡排序策略
class BubbleSort : public SortStrategy {
public:void sort(std::vector<int>& data) override {std::cout << "使用冒泡排序" << std::endl;// 实现冒泡排序逻辑...}
};// 快速排序策略
class QuickSort : public SortStrategy {
public:void sort(std::vector<int>& data) override {std::cout << "使用快速排序" << std::endl;// 实现快速排序逻辑...}
};// ----------------- 3. 上下文类(Context) -----------------
class Sorter {
private:std::unique_ptr<SortStrategy> strategy; // 使用智能指针管理策略对象public:// 设置策略void setStrategy(std::unique_ptr<SortStrategy> newStrategy) {strategy = std::move(newStrategy);}// 执行排序void executeSort(std::vector<int>& data) {if (strategy) {strategy->sort(data);} else {std::cout << "未设置排序策略!" << std::endl;}}
};// ----------------- 客户端代码 -----------------
int main() {Sorter sorter;std::vector<int> data = {5, 2, 7, 1, 3};// 动态切换策略sorter.setStrategy(std::make_unique<BubbleSort>());sorter.executeSort(data); // 输出:使用冒泡排序sorter.setStrategy(std::make_unique<QuickSort>());sorter.executeSort(data); // 输出:使用快速排序return 0;
}
应用场景:

游戏中的角色行为:角色根据状态切换攻击、防御、逃跑策略。

动态使用不同的算法。

观察者模式:

定义对象间的一对多依赖关系,当一个对象(主题)状态改变时,所有依赖它的对象(观察者)会自动收到通知并更新。

应用场景:订阅-通知机制,实现松耦合的一对多事件处理。比如气象观测,观测机器观察到了数据,通知各类的软件。

中介者模式:

用一个中介对象(Mediator)来封装一组对象(Colleague)之间的交互,从而减少对象间的直接耦合。所有对象通过中介者通信,而不是直接相互引用。

应用场景:聊天室

模版模式:

在父类中定义一个规定了算法的执行步骤和顺序的模板方法,声明为 final,再将算法中的步骤声明为抽象方法或虚函数,由子类具体实现。

#include <iostream>// 抽象基类:定义饮料制作的模板
class Beverage {
public:// 模板方法(final 禁止子类修改流程)void prepareBeverage() final {boilWater();brew();addCondiments();pourInCup();}protected:// 具体步骤由子类实现virtual void brew() = 0;virtual void addCondiments() = 0;// 公共步骤(直接复用)void boilWater() {std::cout << "煮沸水" << std::endl;}void pourInCup() {std::cout << "倒入杯子" << std::endl;}virtual ~Beverage() = default;
};// 具体子类:咖啡
class Coffee : public Beverage {
protected:void brew() override {std::cout << "冲泡咖啡粉" << std::endl;}void addCondiments() override {std::cout << "加糖和牛奶" << std::endl;}
};// 具体子类:茶
class Tea : public Beverage {
protected:void brew() override {std::cout << "浸泡茶叶" << std::endl;}void addCondiments() override {std::cout << "加柠檬" << std::endl;}
};// 客户端代码
int main() {Beverage* coffee = new Coffee();coffee->prepareBeverage();// 输出:// 煮沸水// 冲泡咖啡粉// 加糖和牛奶// 倒入杯子Beverage* tea = new Tea();tea->prepareBeverage();// 输出:// 煮沸水// 浸泡茶叶// 加柠檬// 倒入杯子delete coffee;delete tea;return 0;
}
应用场景:

比如餐厅服务员的游戏,制作可乐,雪碧什么的饮料都是一样的步骤,就可以设定一个制作饮料的类,里面规定制作饮料的步骤。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

STM32上实现简化版的AUTOSAR DEM模块

文章目录 摘要摘要 在一些可以不使用AUTOSAR的项目中,往往也有故障检测和DTC存储的需求,开发一套类似于AUTOSAR DEM模块的软件代码,能够满足DTC的检出和存储,使用FalshDB代替Nvm模块,轻松构建持久化存储,如果你也有这样的需求,请阅读本篇,希望能够帮到你。 /*********…

html css网页制作成品——糖果屋网页设计(4页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…

Postman下载安装及简单入门

一&#xff0e;Postman简介 Postman是一款API测试工具&#xff0c;可以帮助开发、测试人员发送HTTP请求&#xff0c;与各种API进行交互&#xff0c;并分析响应 二&#xff0e;下载与安装 访问Postman官网&#xff08;https://www.postman.com/&#xff09;&#xff0c;下载适…

免费blender模型网站推荐

前言:博主最近在玩blender建模,有时为了节省时间想用现成的模型,网上零零碎碎的大多多需要付费,自己找了些好用且免费的blender素材库网站,希望对你有帮助 综合资源网站 Blender布的 网址:https://blenderco.cn/ 简介:提供上万个Blender模型、插件、贴图资源,更新频率高…

基于C语言的简单HTTP Web服务器实现

1. 概述 本案例使用C语言实现了一个简单的HTTP服务器&#xff0c;能够处理客户端的GET请求&#xff0c;并返回静态文件&#xff08;如HTML、图片等&#xff09;。在此案例中案例&#xff0c;我们主要使用的知识点有&#xff1a; Socket编程&#xff1a;基于TCP协议的Socket通信…

大型语言模型与强化学习的融合:迈向通用人工智能的新范式

1. 引言 大型语言模型&#xff08;LLM&#xff09;在自然语言处理领域的突破&#xff0c;展现了强大的知识存储、推理和生成能力&#xff0c;为人工智能带来了新的可能性。强化学习&#xff08;RL&#xff09;作为一种通过与环境交互学习最优策略的方法&#xff0c;在智能体训…

langchain--LCEL

文章目录 介绍优势运行接口 介绍 LCEL的全称是Lang Chain Expression Language。其实他的用处就是使用“|”运算符链接LangChain应用的各个组件。 是一种声明式的方法来链接Langchain组件。LCEL从第一天起就被设计为支持将原型投入生产&#xff0c;无需代码更改&#xff0c;从…

PyQt基础——简单的窗口化界面搭建以及槽函数跳转

一、代码实现 import sysfrom PyQt6.QtGui import QPixmap from PyQt6.QtWidgets import QApplication, QWidget, QPushButton, QLabel, QLineEdit, QMessageBox from PyQt6.uic import loadUi from PyQt6.QtCore import Qtclass LoginWindow(QWidget):def __init__(self):sup…

Android 11.0 监听某个app启动或者退出功能实现

1.前言 在进行11.0的系统定制开发中,在某些app的定制过程中,需要知道某个app的启动记录和退出记录, 所以就需要监听某个app的启动和退出的过程,需要在Activity的生命周期中来实现监听功能 2.监听某个app启动或者退出功能实现的核心类 frameworks\base\core\java\android…

再谈 Multiscale deformable attention

文章目录 DCN 可变形卷积单尺度 deformable attention多尺度&#xff08;multiscale&#xff09; deformable attention精华代码&#xff1a;deformbale attentionattention 计算&#xff1a;获取不同尺度参考点&#xff1a; DCN 可变形卷积 deformable attention 灵感来源可变…

Java 大视界 -- Java 大数据在智慧文旅虚拟导游与个性化推荐中的应用(130)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…

多源 BFS_多源最短路(十八)542. 01 矩阵 中等 超级源点思想

542. 01 矩阵 给定一个由 0 和 1 组成的矩阵 mat &#xff0c;请输出一个大小相同的矩阵&#xff0c;其中每一个格子是 mat 中对应位置元素到最近的 0 的距离。 两个相邻元素间的距离为 1 。 示例 1&#xff1a; 输入&#xff1a;mat [[0,0,0],[0,1,0],[0,0,0]] 输出&#xff…

Ubuntu24.04 LTS 版本 Linux 系统在线和离线安装 Docker 和 Docker compose

一、更换软件源并更新系统 在 Ubuntu 24.04 LTS 中&#xff0c;系统引入了全新的软件源配置格式。现在的源配置文件内容更加结构化且清晰&#xff0c;主要包含了软件类型 (Types)、源地址 (URIs)、版本代号 (Suites) 以及组件 (Components) 等信息。 # cat /etc/apt/sources.li…

c++介绍智能指针 十二(2)

智能指针share_ptr,与unique_ptr不同&#xff0c;多个shar_ptr对象可以共同管理一个指针&#xff0c;它们通过一个共同的引用计数器来管理指针。当一个智能指针对象销毁时&#xff0c;计数器减一。当计数器为0时&#xff0c;会将所指向的内存对象释放。 #include<memory>…

react和vue 基础使用对比

1.实现功能&#xff08;ts&#xff09; 0.基础属性使用 1.组件直接的通信 2.useState 动态修改值 3.循环遍历功能 4.实现类型vue 的 watch &#xff0c;filter&#xff0c;computed 属性功能 5.实现类似vue2的生命周期 5.类型vue v-if功能的实现 2.文件结构图 3.具体代码 in…

深度学习 常见优化器

一、基础优化器 随机梯度下降&#xff08;SGD&#xff09; • 核心&#xff1a;∇θJ(θ) η * ∇θJ(θ) • 特点&#xff1a;学习率固定&#xff0c;收敛路径震荡大 • 适用场景&#xff1a;简单凸优化问题 • 改进方向&#xff1a;动量加速 二、动量系优化器 2. SGD with…

监控快手关注列表更新以及去视频水印视频

def printData(self):if len(self.UpdateDataList) > 0:self.UpdateDataList sorted(self.UpdateDataList, keylambda x: x[minutes]) # 先更新的在前sucess 0for index, video in enumerate(self.UpdateDataList):minutes video[minutes]if minutes > self.updateIn…

前端 JavaScript 中快速发起多个下载请求时,解决浏览器的并发下载连接限制

为什么会漏掉链接&#xff1f; 当你在前端 JavaScript 中快速发起多个下载请求时&#xff0c;浏览器可能无法同时处理所有请求&#xff0c;导致一些请求被忽略。这通常与浏览器的并发连接限制有关&#xff0c;例如 Chrome 可能限制每秒下载 10 个文件。 如何避免漏掉链接&…

如何修改桌面图标——文件夹图标(Windows 10)

修改文件夹图标 EX&#xff1a;新建文件夹&#xff0c;程序创建文件夹等 修改桌面文件夹图标&#xff0c;打开右键菜单功能项&#xff0c;点击“属性” 在属性窗口页面找到并单击自定义&#xff0c;然后点击“更改图标” 从列表中选择喜欢的图标&#xff0c;或点击浏览选择个…

LiveCommunicationKit OC 实现

一、实现效果: ‌ LiveCommunicationKit‌是苹果公司在iOS 17.4、watchOS 10.4和visionOS 1.1中引入的一个新框架,旨在优化VoIP通话的交互体验。该框架提供了与