详解23种设计模式

设计模式(Design Patterns)一般分为三大类:创建型模式结构型模式行为型模式

1. 创建型模式(Creational Patterns)

这些模式主要关注对象的创建过程,目的是通过控制对象的创建,来避免复杂性并提升灵活性。

1.1 单例模式(Singleton)
  • 定义:确保一个类只有一个实例,并提供一个全局访问点。
  • 使用场景:需要一个全局唯一的对象时,如配置类、日志管理类。
1.2 工厂方法模式(Factory Method)
  • 定义:定义一个用于创建对象的接口,但由子类决定实例化哪一个类。
  • 使用场景:当需要让子类决定创建哪种对象时,如不同类型的产品创建。
1.3 抽象工厂模式(Abstract Factory)
  • 定义:提供一个接口,用于创建一系列相关或依赖的对象,而无需指定它们的具体类。
  • 使用场景:当产品有多个维度或系列时,如跨平台 UI 组件。
1.4 建造者模式(Builder)
  • 定义:将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。
  • 使用场景:构建复杂对象时,尤其是涉及多个步骤的创建过程,如创建多步的表单。
1.5 原型模式(Prototype)
  • 定义:通过复制已有对象来创建新的对象,而不是通过实例化类。
  • 使用场景:当创建新对象的代价比较昂贵时,如对象初始化需要消耗较多资源。

2. 结构型模式(Structural Patterns)

结构型模式关注类或对象的组合,目的是帮助设计更灵活、松耦合的结构。

2.1 适配器模式(Adapter)
  • 定义:将一个类的接口转换为客户希望的另一个接口,解决接口不兼容的问题。
  • 使用场景:当现有类不能与其他代码兼容时,如新旧系统的对接。
2.2 桥接模式(Bridge)
  • 定义:将抽象部分与其实现部分分离,使它们可以独立变化。
  • 使用场景:需要在抽象和具体实现之间保持灵活性,如图形渲染系统中不同平台的渲染实现。
2.3 装饰器模式(Decorator)
  • 定义:动态地给对象添加新的功能,而不影响其他对象。
  • 使用场景:当不希望通过继承来增加类的功能时,如动态增加组件的功能。
2.4 组合模式(Composite)
  • 定义:将对象组合成树形结构以表示“部分-整体”的层次结构。
  • 使用场景:当需要处理对象层次结构时,如文件系统、UI 组件树。
2.5 外观模式(Facade)
  • 定义:为子系统中的一组接口提供一个一致的接口,简化客户端的使用。
  • 使用场景:为复杂的子系统提供一个简单的入口,如操作数据库的统一接口。
2.6 享元模式(Flyweight)
  • 定义:通过共享已经存在的对象来减少内存消耗。
  • 使用场景:当系统中存在大量相似对象时,如大量图形对象的共享。
2.7 代理模式(Proxy)
  • 定义:为其他对象提供一种代理以控制对该对象的访问。
  • 使用场景:需要在访问对象前后加入额外的操作时,如虚拟代理、远程代理。

3. 行为型模式(Behavioral Patterns)

行为型模式关注对象之间的通信,目的是提高系统中对象的交互方式。

3.1 模板方法模式(Template Method)
  • 定义:定义一个操作的骨架,而将一些步骤延迟到子类中。模板方法允许子类在不改变算法结构的情况下重新定义算法的某些步骤。
  • 使用场景:有固定步骤但部分步骤需要不同实现时,如业务处理流程。
3.2 策略模式(Strategy)
  • 定义:定义一系列算法,将每个算法封装起来,并使它们可以相互替换。
  • 使用场景:需要在运行时选择不同的算法时,如排序算法的选择。
3.3 观察者模式(Observer)
  • 定义:定义对象间一种一对多的依赖关系,当一个对象的状态发生改变时,其相关依赖对象都能收到通知并自动更新。
  • 使用场景:对象间存在依赖关系时,如事件系统、发布-订阅模式。
3.4 状态模式(State)
  • 定义:允许对象在其内部状态改变时改变其行为。
  • 使用场景:对象有多个状态,每个状态的行为不同时,如状态机、事务处理。
3.5 命令模式(Command)
  • 定义:将请求封装为对象,使得可以用不同的请求来参数化其他对象。
  • 使用场景:需要将操作请求封装为对象时,如命令队列、回滚操作。
3.6 职责链模式(Chain of Responsibility)
  • 定义:将多个处理器组织成一条链,沿着链传递请求,直到有对象处理它为止。
  • 使用场景:多个对象都有可能处理请求,但处理者未知时,如审批流程。
3.7 中介者模式(Mediator)
  • 定义:通过一个中介对象来封装一系列对象之间的交互。
  • 使用场景:多个对象之间的通信复杂时,如聊天室中消息的转发。
3.8 迭代器模式(Iterator)
  • 定义:提供一种方法顺序访问集合对象中的各个元素,而不暴露其内部表示。
  • 使用场景:需要遍历集合对象时,如链表、数组等集合类。
3.9 备忘录模式(Memento)
  • 定义:在不破坏封装的前提下,捕获对象的内部状态,并在之后进行恢复。
  • 使用场景:需要保存和恢复对象状态时,如撤销操作。
3.10 解释器模式(Interpreter)
  • 定义:为某个语言定义文法,并定义一个解释器来处理该语言中的句子。
  • 使用场景:当需要实现一种简单语言的解释器时,如正则表达式解析器。

4. 具体例子

4.1 单例模式
#include <iostream>
#include <mutex>class Singleton {
private:// 私有构造函数,确保外部无法直接实例化Singleton() {std::cout << "Singleton instance created.\n";}// 禁用拷贝构造和赋值运算符Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;// 静态指针,指向唯一的实例static Singleton* instance;static std::mutex mtx;public:// 提供获取唯一实例的接口static Singleton* getInstance() {// 使用双重检查锁定以保证线程安全if (instance == nullptr) {std::lock_guard<std::mutex> lock(mtx);if (instance == nullptr) {instance = new Singleton();}}return instance;}void showMessage() {std::cout << "Hello from Singleton instance!\n";}
};// 初始化静态成员
Singleton* Singleton::instance = nullptr;
std::mutex Singleton::mtx;int main() {Singleton* s1 = Singleton::getInstance();Singleton* s2 = Singleton::getInstance();s1->showMessage();// 输出两个指针是否相等,验证只有一个实例std::cout << (s1 == s2) << std::endl;  // 输出 1,表示是同一个实例return 0;
}
4.2 工厂方法模式
#include <iostream>
#include <memory>// 抽象产品类
class Product {
public:virtual void use() = 0;virtual ~Product() = default;
};// 具体产品类1
class ConcreteProductA : public Product {
public:void use() override {std::cout << "Using Product A\n";}
};// 具体产品类2
class ConcreteProductB : public Product {
public:void use() override {std::cout << "Using Product B\n";}
};// 抽象工厂类
class Creator {
public:virtual std::unique_ptr<Product> createProduct() = 0;virtual ~Creator() = default;
};// 具体工厂类1
class ConcreteCreatorA : public Creator {
public:std::unique_ptr<Product> createProduct() override {return std::make_unique<ConcreteProductA>();}
};// 具体工厂类2
class ConcreteCreatorB : public Creator {
public:std::unique_ptr<Product> createProduct() override {return std::make_unique<ConcreteProductB>();}
};int main() {// 使用工厂 A 创建产品std::unique_ptr<Creator> creatorA = std::make_unique<ConcreteCreatorA>();std::unique_ptr<Product> productA = creatorA->createProduct();productA->use();// 使用工厂 B 创建产品std::unique_ptr<Creator> creatorB = std::make_unique<ConcreteCreatorB>();std::unique_ptr<Product> productB = creatorB->createProduct();productB->use();return 0;
}
4.3 策略模式
#include <iostream>
#include <memory>// 抽象策略类
class Strategy {
public:virtual void execute() const = 0;virtual ~Strategy() = default;
};// 具体策略类1
class ConcreteStrategyA : public Strategy {
public:void execute() const override {std::cout << "Executing Strategy A\n";}
};// 具体策略类2
class ConcreteStrategyB : public Strategy {
public:void execute() const override {std::cout << "Executing Strategy B\n";}
};// 上下文类
class Context {
private:std::unique_ptr<Strategy> strategy;public:// 设置策略void setStrategy(std::unique_ptr<Strategy> s) {strategy = std::move(s);}// 执行策略void executeStrategy() const {if (strategy) {strategy->execute();}}
};int main() {Context context;// 选择并执行策略 Acontext.setStrategy(std::make_unique<ConcreteStrategyA>());context.executeStrategy();// 切换到策略 Bcontext.setStrategy(std::make_unique<ConcreteStrategyB>());context.executeStrategy();return 0;
}
4.4 观察者模式
#include <iostream>
#include <vector>
#include <memory>// 观察者接口
class Observer {
public:virtual void update(int newState) = 0;virtual ~Observer() = default;
};// 被观察者(主题)类
class Subject {
private:std::vector<std::shared_ptr<Observer>> observers;int state;public:void attach(const std::shared_ptr<Observer>& observer) {observers.push_back(observer);}void setState(int newState) {state = newState;notify();}void notify() {for (const auto& observer : observers) {observer->update(state);}}
};// 具体观察者类
class ConcreteObserver : public Observer {
private:std::string name;public:explicit ConcreteObserver(std::string n) : name(std::move(n)) {}void update(int newState) override {std::cout << "Observer " << name << " notified with state: " << newState << "\n";}
};int main() {Subject subject;auto observer1 = std::make_shared<ConcreteObserver>("Observer1");auto observer2 = std::make_shared<ConcreteObserver>("Observer2");subject.attach(observer1);subject.attach(observer2);subject.setState(10);  // 通知所有观察者return 0;
}

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

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

相关文章

Zilliz获Forrester报告全球第一;OB支持向量能力;Azure发布DiskANN;阿里云PG发布内置分析引擎

重要更新 1. Azure发布PostgreSQL向量索引扩展DiskANN&#xff0c;声称在构建HNSW/IVFFlat索引上&#xff0c;速度、精准度都超越pg_vector&#xff0c;并解决了pg_vector长期存在的偶发性返回错误结果的问题( [1] )。 2. 阿里云RDS PostgreSQL 发布AP加速引擎&#xff08;rds…

修改MYSQL库的默认字符集和校验规则

修改mysql的默认配置文件my.cnf。 vim /etc/my.cnf 如果没有这个文件就可能在这个路径&#xff1a;/etc/mysql/my.cnf 在 [mysqld] 部分下&#xff0c;添加或修改以下设置&#xff1a; character-set-server [要修改的字符集] collation-server [要修改的校验规则] 保存文…

Git客户端使用之命令行

一、git客户端命令行的使用 1、创建本地用户并绑定ssh-key到gitlab #在本地注册用户,这个用户随便创建它就是与git仓库连接的一个用户&#xff0c;不过最好喝git仓库用户一样有利于区分。 git config --global user.name "wenqiang1" git config --global user.ema…

SpringBoot+Vue+Uniapp智能社区服务小程序系统(源码+lw+部署文档+讲解等)

项目运行截图 技术框架 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的开源框架。它采用约定大于配置的理念&#xff0c;提供了一套默认的配置&#xff0c;让开发者可以更专注于业务逻辑而不是配置文件。Spring Boot 通过自动化配置和约…

web 0基础第一节 文本标签

学习web语言 首先推荐安装一个vs code 的软件 这个普及度更广一点 兼容性好 网上有很多下载的教程 这里就直接从 html5 的内容开始说了. 这是一个html文件的基本结构 在vs code 中使用英文的 ! 可快捷设置这样的结构 <!-- --> 是在html写注释的结构 以后的…

【Java数据结构】优先级队列(堆)

【本节目标】 1. 掌握堆的概念及实现 2. 掌握 PriorityQueue 的使用 一. 优先级队列 1 概念 前面学过队列&#xff0c;队列是一种先进先出 (FIFO) 的数据结构 &#xff0c;但有些情况下&#xff0c; 操作的数据可能带有优先级&#xff0c;一般出队 列时&#xff0c;可…

【前端】如何制作一个自己的网页(8)

以下内容接上文。 CSS的出现&#xff0c;使得网页的样式与内容分离开来。 HTML负责网页中有哪些内容&#xff0c;CSS负责以哪种样式来展现这些内容。因此&#xff0c;CSS必须和HTML协同工作&#xff0c;那么如何在HTML中引用CSS呢&#xff1f; CSS的引用方式有三种&#xff1…

【LeetCode算法笔记】Day1:动态规划基础

目录 动态规划简介动态规划的定义动态规划的核心思想动态规划的简单例子 动态规划特征最优子结构性质重复子问题性质无后效应 动态规划的基本思路 动态规划简介 动态规划的定义 简称DP,是一种求解多阶段决策过程最优化问题的方法。在动态规划中&#xff0c;通过把原问题分解为…

Golang | Leetcode Golang题解之第478题在圆内随机生成点

题目&#xff1a; 题解&#xff1a; type Solution struct {radius, xCenter, yCenter float64 }func Constructor(radius, xCenter, yCenter float64) Solution {return Solution{radius, xCenter, yCenter} }func (s *Solution) RandPoint() []float64 {r : math.Sqrt(rand.…

MySQL面试专题-索引

一、MySQL为什么要选择B树来存储索引&#xff1f; MySQL的索引选择B树作为数据结构来进行存储&#xff0c;其本质原因在于可以减少IO次数&#xff0c;提高查询效率&#xff0c;简单来说就是保证在树的高度不变的情况下可以存储更多的数据。 &#xff08;一&#xff09;IO角度 在…

约克VRF打造舒适绿色无污染的生活环境

在生活的各个方面&#xff0c;约克VRF都采取了多种措施助力碳中和。 采用国际领先的空气源热泵技术&#xff0c;只需少量电力就可将空气中的能量转化为室内热量&#xff0c;被称为“大自然的搬运工”&#xff01;COP能效值最高可达4.24&#xff08;每用一度电产生4.24度电热量&…

第 3 章:使用 Vue 脚手架

1. 初始化脚手架 1.1 说明 Vue 脚手架是 Vue 官方提供的标准化开发工具&#xff08;开发平台&#xff09;。最新的版本是 5.x。文档: https://cli.vuejs.org/zh/ 1.2 具体步骤 第一步&#xff08;仅第一次执行&#xff09;&#xff1a;全局安装vue/cli。 npm install -g vu…

衡石分析平台系统分析人员手册-仪表盘控件概述

控件​ 控件是仪表盘的基本组成单位。控件种类很多&#xff0c;有展示分析数据的图表类类控件&#xff0c;有展示图片、文字的展示类控件&#xff0c;还有可导出数据、刷新数据、过滤数据等功能类控件。一个完整的仪表盘由多种不同功能的控件构成。 控件类型​ 根据控件是否展…

海外动态代理IP的优缺点有哪些? 动态代理IP与静态代理IP的区别是什么?

海外动态代理IP的优缺点分析 在全球化的数字时代&#xff0c;网络安全和隐私保护的重要性日益凸显。海外动态代理IP作为一种灵活的网络工具&#xff0c;因其独特的特性在多个领域得到了广泛应用。然而&#xff0c;正如任何技术一样&#xff0c;它也有其优点和局限性。以下&…

Shell案例之一键部署mysql

1.问题 我认为啊学习就是一个思考的过程&#xff0c;思考问题的一个流程应该是&#xff1a;提出问题&#xff0c;分析问题&#xff0c;解决问题 在shell里部署mysql服务时&#xff0c;我出现一些问题&#xff1a; 1.安装mysql-server时&#xff0c;没有密钥&#xff0c;安装…

PE结构之导入表

流程图: 文件中\样式 加载到进程中时 加载到进程中时的过程,一张图不够放 续图 整个流程 补充导入表结构IMAGE_IMPORT_DESCRIPTOR 中的ForwarderChain字段, 该解释为 "某个导入模块涉及转发&#xff08;即该模块的某些函数从其他模块转发过来&#xff09;&#xff0c;那么…

windows安装deepspeed setup.py 207行找不到文件

一直报莫名奇妙的错误&#xff0c;查了半天也没查到 去看了一下源码&#xff0c;需要安装git&#xff0c;我没有安装 git命令获得信息也没啥用 直接注释掉 成功运行

YOLO11改进|注意力机制篇|引入轴向注意力Axial Attention

目录 一、【Axial Attention】注意力机制1.1【Axial Attention】注意力介绍1.2【Axial Attention】核心代码二、添加【Axial Attention】注意力机制2.1STEP12.2STEP22.3STEP32.4STEP4三、yaml文件与运行3.1yaml文件3.2运行成功截图一、【Axial Attention】注意力机制 1.1【Axi…

【JPCS独立出版,EI检索稳定】第三届能源互联网及电力系统国际学术会议(ICEIPS 2024)

第三届能源互联网及电力系统国际学术会议&#xff08;ICEIPS 2024&#xff09; 2024 3rd International Conference on Energy Internet and Power Systems ICEIPS 2024已成功申请JPCS - Journal of Physics: Conference Series (ISSN:1742-6596) ICEIPS 2024独立出版&…

TCP——Socket

应用进程只借助Socket API发和收但是不关心他是怎么进行传和收的 数据结构 图示Socket连接 捆绑属于隐式捆绑