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

从C++示例理解开闭原则

开闭原则要求我们在编写代码时,尽量不去修改原先的代码,当出现新的业务需求时,应该通过增加新代码的形式扩展业务而不是对原代码进行修改。

假如我们现在有一批产品,每个产品都具有颜色和大小,产品其定义如下:

enum class Color { Red, Green, Blue };
enum class Size { Small, Medium, Large };struct Product 
{string name;Color color;Size size;
};

这里 Product 定义为 struct 是因为 struct 默认的访问权限是公有方便书写,并且 struct 除了访问权限其他语法与 class 相同。

我们现在需要给一组产品提供过滤功能。于是定义下面的过滤器:

struct ProductFilter 
{using Items = vector<Product*>;
}

当我们需要针对 Color 的过滤时,我们增加方法 by_color:

struct ProductFilter
{using Items = vector<Product*>;// 新增方法 by_colorItems by_color(Items items, Color color);
}

当我们需要针对 Size 的过滤时,我们增加方法 by_size:

struct ProductFilter
{using Items = vector<Product*>;Items by_color(Items items, Color color);// 新增方法 by_sizeItems by_size(Items items, Size size);
}

当我们需要针对 Color 和 Size 同时满足的筛选时,再添加…

可以看出当我们有新的需求时,必须要对 ProductFilter 类进行修改,并没有遵循开闭原则,所以我们希望重新设计使这个程序满足开闭原则,重构主要用到 template 模版编程。

首先,我们需要将过滤器分为两部分:过滤器本身和指定的过滤规范。

首先我们先定义一个规范接口,不同的过滤需求将通过继承此接口来满足:

template <typename T> 
struct Specification 
{virtual bool is_satisfied(T* item) = 0;
}

这里的类型 T 可以由我们自由地指定,我们可以指定为类型 Product 也可以指定为其他类型,这就意味着,这个规范将不再局限于 Product,我们可以在任何其他类型中使用它。

接下来是过滤器接口的定义:

template <typename T>
struct Filter
{virtual vector<T*> filter(vector<T*> items, Specification<T>& spec) const = 0;
}

同样地,这里使用模版编程来让过滤器不局限于对 Product 进行过滤。在虚函数 filter 中,我们接受 T 类型的容器,并通过 Specification 指定过滤规范。

然后我们需要继承 Filter 实现针对于 Product 的过滤器:


```cpp
struct BetterFilter: Filter<Product>
{vector<Product*> filter(vector<Product*> items, Specification<Product>& spec) const override {vector<Product*> result;for(auto& p: items) {if(spec.is_satisfied(p)) {result.push_back(p);}}return result;}
};

在 filter 方法中我们会调用 Specification& 中实现过滤规范对 vector<Product*> 容器中的对象进行筛选。

当我们有了以上的过滤器和规范接口之后,我们便可以在不修改代码的情况下,扩展业务了。

比如:当我们需要对于颜色的过滤器时,我们只需要继承 Specification 并覆盖 is_satisfied 方法来实现颜色的过滤法则,即可达到我们的目的:

// 颜色筛选规范
struct ColorSpecification : Specification<Product>
{Color color;explicit ColorSpecification(const Color& color) : color(color) {}bool is_satisfied(Product* item) override {return item->color == color;}
};

当我们需要针对 Size 的过滤时:

// 大小筛选规范
struct SizeSpecification : Specification<Product>
{Size size;explicit SizeSpecification(const Size& size) : size(size) {}bool is_satisfied(Product* item) override {return item->size == size;}
};

可以看到,我们不再需要修改过滤器来达到我们的目的,很显然我们遵从了开闭原则。

需要查看完整的示例代码可以访问 Github 仓库 GnCDesignPatterns。

参考:C++20设计模式

相关文章:

从C++示例理解开闭原则

开闭原则要求我们在编写代码时&#xff0c;尽量不去修改原先的代码&#xff0c;当出现新的业务需求时&#xff0c;应该通过增加新代码的形式扩展业务而不是对原代码进行修改。 假如我们现在有一批产品&#xff0c;每个产品都具有颜色和大小&#xff0c;产品其定义如下&#xf…...

Java线程池execute和submit的区别

前言 ThreadPoolExecutor提供了两种方法来执行异步任务&#xff0c;分别是execute和submit&#xff0c;也是日常开发中经常使用的方法&#xff0c;那么它俩有什么区别呢&#xff1f; 语义不同 首先是语义上的不同。execute声明在Executor接口&#xff0c;它接受一个Runnable…...

什么是json

JSON&#xff08;JavaScript Object Notation&#xff09;是一种轻量级的数据交换格式。它基于JavaScript编程语言的一个子集&#xff0c;但是由于其文本格式清晰、易于解析&#xff0c;并且能够以键/值对的形式表示复杂的数据结构&#xff0c;因此它被广泛用于不同的编程语言和…...

基于聚类和回归分析方法探究蓝莓产量影响因素与预测模型研究附录

&#x1f31f;欢迎来到 我的博客 —— 探索技术的无限可能&#xff01; &#x1f31f;博客的简介&#xff08;文章目录&#xff09; 目录 背景数据说明数据来源思考 附录数据预处理导入包以及数据读取数据预览数据处理 相关性分析聚类分析数据处理确定聚类数建立k均值聚类模型 …...

java类型转换

pom <dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.76</version></dependency>BeanUtils 在这里插入代码片list<Map>转换成List<bean> public static <T> L…...

Unity打包Webgl端进行 全屏幕自适应

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一&#xff1a;修改 index.html二&#xff1a;将非移动端设备&#xff0c;canvas元素的宽度和高度会设置为100%。三&#xff1a;修改style.css总结 下载地址&#x…...

36. 【Java教程】输入输出流

本小节将会介绍基本输入输出的 Java 标准类&#xff0c;通过本小节的学习&#xff0c;你将了解到什么是输入和输入&#xff0c;什么是流&#xff1b;输入输出流的应用场景&#xff0c;File类的使用&#xff0c;什么是文件&#xff0c;Java 提供的输入输出流相关 API 等内容。 1…...

Visual C++2010学习版详细安装教程(超详细图文)

Visual C 介绍 Visual C&#xff08;简称VC&#xff09;是微软公司推出的一种集成开发环境&#xff08;IDE&#xff09;&#xff0c;主要用于开发C和C语言的应用程序。它提供了强大的编辑器、编译器、调试器、库和框架支持&#xff0c;以及丰富的工具和选项&#xff0c;使得开…...

matlab图像处理入门

matlab在学校科研&#xff0c;仿真及基于模型开发的工作中有重要作用&#xff0c;在图像处理方面由于省去了复杂的上位机开发流程&#xff0c;因此可以让用户快速开发验证算法&#xff0c;下面简要介绍其在图像处理方面的应用。 matlab开发图像处理算法的流程主要是&#xff0c…...

关于线程池面试题,使用“豆包”训练答案

我提问&#xff1a; 问题描述 下面是一个有关线程池调度的面试真题&#xff0c;来自于疯狂创客圈社群&#xff1a; 一个线程池的核心线程数为10个&#xff0c;最大线程数为20个&#xff0c;阻塞队列的容量为30。现在提交45个 任务&#xff0c;每个任务的耗时为500毫秒。 请问&…...

【WRF理论第二期】模型目录介绍

WRF理论第二期&#xff1a;模型目录介绍 1 WRF主目录2 WPS主目录3 编译后的可执行文件4 运行目录参考 了解 WRF 模型的目录结构有助于有效地管理和操作模型&#xff0c;从而确保模拟和分析工作的顺利进行。以下分解介绍WRF主目录、WPS主目录等。 Github-wrf-model/WRF 1 WRF…...

从了解到掌握 Spark 计算框架(一)Spark 简介与基础概念

文章目录 什么是 Spark&#xff1f;核心特点 Spark 对比 MapReduceSpark 编程模型RDDDataFrameDataset Spark 运行模式Spark 生态 什么是 Spark&#xff1f; Spark 是一个基于内存的分布式计算框架&#xff0c;最初由加州大学伯克利分校的 AMPLab 开发&#xff0c;后来捐赠给了…...

linux bind函数

bind函数的目的是让把客户端对应的端口(port)地址和ip地址绑定到客户端 [参考](Linux之bind 函数&#xff08;详细篇&#xff09;_linux bind函数-CSDN博客)...

Flink系列一:flink光速入门 (^_^)

引入 spark和flink的区别&#xff1a;在上一个spark专栏中我们了解了spark对数据的处理方式&#xff0c;在 Spark 生态体系中&#xff0c;对于批处理和流处理采用了不同的技术框架&#xff0c;批处理由 Spark-core,SparkSQL 实现&#xff0c;流处理由 Spark Streaming 实现&am…...

PySpark特征工程(III)--特征选择

有这么一句话在业界广泛流传&#xff1a;数据和特征决定了机器学习的上限&#xff0c;而模型和算法只是逼近这个上限而已。由此可见&#xff0c;特征工程在机器学习中占有相当重要的地位。在实际应用当中&#xff0c;可以说特征工程是机器学习成功的关键。 特征工程是数据分析…...

Mongodb的数据库简介、docker部署、操作语句以及java应用

Mongodb的数据库简介、docker部署、操作语句以及java应用 本文主要介绍了mongodb的基础概念和特点&#xff0c;以及基于docker的mongodb部署方法&#xff0c;最后介绍了mongodb的常用数据库操作语句&#xff08;增删改查等&#xff09;以及java下的常用语句。 一、基础概念 …...

七大战略性新兴产业崭露头角:新能源电燃灶或将成为未来厨房新宠

近日&#xff0c;在国家发布的七大战略性新兴产业名单中&#xff0c;新能源产业赫然在列&#xff0c;作为其中的重要组成部分&#xff0c;华火新能源电燃灶凭借其独特的优势&#xff0c;正逐渐走进人们的视野&#xff0c;有望成为未来厨房的新宠。 华火新能源电燃灶作为清洁能源…...

C#进阶-用于Excel处理的程序集

在.NET开发中&#xff0c;处理Excel文件是一项常见的任务&#xff0c;而有一些优秀的Excel处理包可以帮助开发人员轻松地进行Excel文件的读写、操作和生成。本文介绍了NPOI、EPPlus和Spire.XLS这三个常用的.NET Excel处理包&#xff0c;分别详细介绍了它们的特点、示例代码以及…...

持续总结中!2024年面试必问 20 道 Kafka面试题(五)

上一篇地址&#xff1a;持续总结中&#xff01;2024年面试必问 20 道 Kafka面试题&#xff08;四&#xff09;-CSDN博客 九、请解释Kafka中的Zookeeper的作用。 在Kafka中&#xff0c;ZooKeeper扮演着至关重要的角色&#xff0c;主要负责集群管理、协调和状态同步等功能。以下…...

Draw.io 使用详细教程

Draw.io 是一款功能强大的在线绘图工具&#xff0c;适用于创建流程图、网络图、组织结构图、UML 图等。以下是详细的使用教程&#xff0c;包括基本操作、快捷键、常用技巧和进阶技巧。 1. 创建新图 选择存储位置 首次使用时&#xff0c;系统会询问你要将图保存到哪里。你可以…...

Android Wi-Fi 连接失败日志分析

1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分&#xff1a; 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析&#xff1a; CTR…...

PHP和Node.js哪个更爽?

先说结论&#xff0c;rust完胜。 php&#xff1a;laravel&#xff0c;swoole&#xff0c;webman&#xff0c;最开始在苏宁的时候写了几年php&#xff0c;当时觉得php真的是世界上最好的语言&#xff0c;因为当初活在舒适圈里&#xff0c;不愿意跳出来&#xff0c;就好比当初活在…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

2024年赣州旅游投资集团社会招聘笔试真

2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务

通过akshare库&#xff0c;获取股票数据&#xff0c;并生成TabPFN这个模型 可以识别、处理的格式&#xff0c;写一个完整的预处理示例&#xff0c;并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务&#xff0c;进行预测并输…...

在WSL2的Ubuntu镜像中安装Docker

Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包&#xff1a; for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机&#xff08;Finite Automaton, FA&#xff09;到正规文法&#xff08;Regular Grammar&#xff09;转换器&#xff0c;它配备了一个直观且完整的图形用户界面&#xff0c;使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

Spring是如何解决Bean的循环依赖:三级缓存机制

1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间‌互相持有对方引用‌,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...

Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问&#xff08;基础概念问题&#xff09; 1. 请解释Spring框架的核心容器是什么&#xff1f;它在Spring中起到什么作用&#xff1f; Spring框架的核心容器是IoC容器&#…...