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

SOLID原则学习,开闭原则(Open Closed Principle, OCP)

在这里插入图片描述

文章目录

  • 1. 定义
  • 2. 开闭原则的详细解释
  • 3. 实现开闭原则的方法
  • 4. 总结


1. 定义

开闭原则(Open-Closed Principle,OCP)是面向对象设计中的五大原则(SOLID)之一,由Bertrand Meyer提出。开闭原则的核心思想是:

软件实体(类、模块、函数等)应该对扩展开放,但对修改关闭。

这意味着,当需求发生变化时,应该通过添加新的代码来扩展系统的行为,而不是修改已有的代码。这样可以减少对现有代码的影响,降低引入新错误的风险,并提高代码的可维护性和可复用性。


2. 开闭原则的详细解释

1. 对扩展开放:当系统需要增加新的功能时,应该允许通过添加新的代码来实现,而不是修改现有的代码。

2. 对修改关闭:一旦一个模块或类已经完成并通过测试,就不应该再修改它的源代码,除非是为了修复bug。


3. 实现开闭原则的方法

为了实现开闭原则,通常会使用以下设计模式或技术:

  • 抽象与多态:通过定义抽象类或接口,允许子类或实现类扩展行为。

  • 策略模式:将算法或行为封装在独立的类中,使得它们可以相互替换。

  • 模板方法模式:定义一个算法的骨架,允许子类在不改变算法结构的情况下重新定义算法的某些步骤。

  • 装饰器模式:动态地为对象添加新的行为,而不改变其原有结构。

实例分析
假设我们有一个简单的图形绘制系统,系统需要支持绘制不同类型的图形(如圆形、矩形等)。最初,系统只支持绘制圆形,但随着需求的变化,我们需要支持绘制矩形。

不符合开闭原则的实现

class Graphic {
public:void drawCircle() {// 绘制圆形的代码}void drawRectangle() {// 绘制矩形的代码}
};void drawAllShapes(Graphic& graphic) {graphic.drawCircle();graphic.drawRectangle();
}

在这个实现中,每当需要增加一个新的图形类型时,我们都需要修改Graphic类,添加新的绘制方法。这违反了开闭原则,因为我们需要修改已有的代码来扩展功能。

符合开闭原则的实现
为了符合开闭原则,我们可以使用抽象和多态来设计系统。

#include <iostream>
#include <vector>// 抽象基类
class Shape {
public:virtual void draw() const = 0;virtual ~Shape() = default;
};// 圆形类
class Circle : public Shape {
public:void draw() const override {std::cout << "Drawing a circle." << std::endl;}
};// 矩形类
class Rectangle : public Shape {
public:void draw() const override {std::cout << "Drawing a rectangle." << std::endl;}
};// 绘制所有图形
void drawAllShapes(const std::vector<Shape*>& shapes) {for (const auto& shape : shapes) {shape->draw();}
}int main() {std::vector<Shape*> shapes;shapes.push_back(new Circle());shapes.push_back(new Rectangle());drawAllShapes(shapes);// 清理内存for (const auto& shape : shapes) {delete shape;}return 0;
}

在这个实现中,我们定义了一个抽象的Shape类,并让Circle和Rectangle继承自Shape。当需要增加新的图形类型时,我们只需要创建一个新的类并实现draw方法,而不需要修改现有的代码。这样,系统对扩展是开放的,对修改是关闭的。


4. 总结

开闭原则是面向对象设计中的重要原则,它鼓励我们通过扩展而不是修改来增加系统的功能。通过使用抽象和多态,我们可以设计出符合开闭原则的系统,从而提高代码的可维护性和可复用性。

相关文章:

SOLID原则学习,开闭原则(Open Closed Principle, OCP)

文章目录 1. 定义2. 开闭原则的详细解释3. 实现开闭原则的方法4. 总结 1. 定义 开闭原则&#xff08;Open-Closed Principle&#xff0c;OCP&#xff09;是面向对象设计中的五大原则&#xff08;SOLID&#xff09;之一&#xff0c;由Bertrand Meyer提出。开闭原则的核心思想是…...

Unreal Engine 5 C++ Advanced Action RPG 七章笔记

第七章 Ranged Enemy 2-Ranged Enemy Starting Weapon 制作新敌人的流程准备 新敌人的武器起始的状态数据自己的战斗能力投射能力自己的行为树 创建角色,添加武器,添加数据,就是继承之前的基类敌人的 运行结果 3-Glacer Starting Stats 看看就行,就是复制曲线表格更改数…...

自动连接校园网wifi脚本实践(自动网页认证)

目录 起因执行步骤分析校园网登录逻辑如何判断当前是否处于未登录状态&#xff1f; 书写代码打包设置开机自动启动 起因 我们一般通过远程控制的方式访问实验室电脑&#xff0c;但是最近实验室老是断电&#xff0c;但重启后也不会自动连接校园网账户认证&#xff0c;远程工具&…...

HTTP/HTTPS ⑤-CA证书 || 中间人攻击 || SSL/TLS

这里是Themberfue ✨上节课我们聊到了对称加密和非对称加密&#xff0c;实际上&#xff0c;单纯地非对称加密并不能保证数据不被窃取&#xff0c;我们还需要一个更加重要的东西——证书 中间人攻击 通过非对称加密生成私钥priKey和公钥pubKey用来加密对称加密生成的密钥&…...

traceroute原理探究

文章中有截图&#xff0c;看不清的话&#xff0c;可以把浏览器显示比例放大到200%后观看。 linux下traceroute的原理 本文通过抓包观察一下linux下traceroute的原理 环境&#xff1a;一台嵌入式linux设备&#xff0c;内网ip是192.168.186.195&#xff0c;其上有192.168.202.…...

50_Lua垃圾回收

1.Lua垃圾回收机制概述 Lua采用了一种自动内存管理机制,称为垃圾回收(Garbage Collection, GC)。垃圾回收的主要目的是回收程序中不再被使用的内存,从而避免内存泄漏。Lua的垃圾回收器负责回收动态分配的对象,如函数、用户数据、表、字符串、线程、内部结构等。Lua的垃圾…...

Git-2-:Cherry-Pick 的使用场景及使用流程

前面我们说了 Git合并、解决冲突、强行回退等解决方案 >> 点击查看 这里再说一下 Cherry-Pick功能&#xff0c;Cherry-Pick不是merge&#xff0c;只是把部分功能代码Cherry-Pick到远程的目标分支 git cherry-pick功能简介&#xff1a; git cherry-pick 是用来从一个分…...

【C++】21.map和set的使用

文章目录 1. 序列式容器和关联式容器2. set系列的使用2.1 set和multiset参考文档2.2 set类的介绍2.3 set的构造和迭代器构造函数&#xff1a;双向迭代器迭代器&#xff1a; 2.4 set的增删查2.5 insert和迭代器遍历使用样例&#xff1a;2.6 find和erase使用样例&#xff1a;2.7 …...

burpsiute的基础使用(2)

爆破模块&#xff08;intruder&#xff09;&#xff1a; csrf请求伪造访问&#xff08;模拟攻击&#xff09;: 方法一&#xff1a; 通过burp将修改&#xff0c;删除等行为的数据包压缩成一个可访问链接&#xff0c;通过本地浏览器访问&#xff08;该浏览器用户处于登陆状态&a…...

ElasticSearch 同义词匹配

synonym.txt 电脑, 计算机, 主机 复印纸, 打印纸, A4纸, 纸, A3 平板电脑, Pad DELETE /es_sku_index_20_20250109 PUT /es_sku_index_20_20250109 {"settings": {"index": {"number_of_shards": "5","number_of_replicas&quo…...

linux RT-Preempt spin lock实现

一、spin_lock概述 Spinlock是linux内核中常用的一种互斥锁机制&#xff0c;和mutex不同&#xff0c;当无法持锁进入临界区的时候&#xff0c;当前执行线索不会阻塞&#xff0c;而是不断的自旋等待该锁释放。正因为如此&#xff0c;自旋锁也是可以用在中断上下文的。也正是因为…...

PySpark广播表连接解决数据倾斜的完整案例

使用PySpark解决数据倾斜问题的完整案例&#xff0c;通过广播表连接的方式来优化性能。 准备数据 假设我们有两张表&#xff0c;一张大表 big_table 和一张小表 small_table &#xff0c;小表将作为广播表。 from pyspark.sql import SparkSession# 初始化SparkSession spar…...

Chromium CDP 开发(十二):为自己的Domain建立custom_config.json

引言 本章详细介绍了如何为自定义的 CDP Domain 创建 custom_config.json 文件&#xff0c;并通过修改 BUILD.gn 文件来确保自定义的配置文件参与编译。我们通过 inspector_protocol_generate 配置段自动生成自定义 Domain 的头文件和实现文件&#xff0c;并成功将其集成到构建…...

【Vue】全局/局部组件使用流程(Vue2为例)

全局组件和局部组件区别 如何使用 全局组件&#xff1a;全局注册后&#xff0c;可以在任意页面中直接使用。局部组件&#xff1a;在页面中需要先导入子组件路径&#xff0c;注册组件才能使用。 适用场景 全局组件&#xff1a;适用于高频使用的组件&#xff0c;如导航栏、业…...

Vue.js组件开发详解

在现代前端开发中&#xff0c;Vue.js 凭借其简洁、高效、灵活的特性&#xff0c;成为了众多开发者的首选框架之一&#xff0c;而组件化开发则是 Vue.js 的核心优势。组件可以将复杂的 UI 界面拆分成一个个独立的、可复用的小块&#xff0c;极大地提高了开发效率和代码的可维护性…...

解决:ubuntu22.04中IsaacGymEnv保存视频报错的问题

1. IsaacGymEnvs项目介绍 IsaacGymEnvs&#xff1a;基于NVIDIA Isaac Gym的高效机器人训练环境 IsaacGymEnvs 是一个基于 NVIDIA Isaac Gym 的开源 Python 环境库&#xff0c;专为机器人训练提供高效的仿真环境。Isaac Gym 是由 NVIDIA 开发的一个高性能物理仿真引擎&#xf…...

深度学习camp-第J7周:对于ResNeXt-50算法的思考

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 &#x1f4cc;你需要解决的疑问&#xff1a;这个代码是否有错&#xff1f;对错与否都请给出你的思考 &#x1f4cc;打卡要求&#xff1a;请查找相关资料、逐步…...

java: 错误: 无效的源发行版:17解决办法

遇到“java: 错误: 无效的源发行版&#xff1a;17”的问题&#xff0c;通常是因为项目设置中指定的Java版本与当前环境不一致导致的。以下是几种可能的解决方案&#xff1a; 检查并升级Java版本&#xff1a;确保你已经安装了支持Java 17的JDK版本。你可以通过命令行输入java -v…...

Docker 安装开源的IT资产管理系统Snipe-IT

一、安装 1、创建docker-compose.yaml version: 3services:snipeit:container_name: snipeitimage: snipe/snipe-it:v6.1.2restart: alwaysports:- "8000:80"volumes:- ./logs:/var/www/html/storage/logsdepends_on:- mysqlenv_file:- .env.dockernetworks:- snip…...

Go语言封装加解密包(AES/DES/RSA)

Go语言封装加解密包&#xff08;AES/DES/RSA&#xff09; 1. Base64编码与解码2. AES加解密3. DES加解密4. RSA加解密5. SHA256哈希6. 单元测试1. AES加解密单元测试2. DES加解密单元测试3. RSA加解密单元测试4. SHA256哈希单元测试测试用例说明 总结 在现代软件开发中&#xf…...

Sodaq_R4X库详解:SARA-R4蜂窝模组嵌入式通信框架

1. Sodaq_R4X库深度解析&#xff1a;面向SARA-R4系列蜂窝模组的嵌入式通信框架1.1 库定位与工程价值Sodaq_R4X是一个专为u-blox SARA-R4系列蜂窝通信模组设计的Arduino兼容C库&#xff0c;其核心目标是将复杂的LTE-M&#xff08;eMTC&#xff09;、NB-IoT及2G&#xff08;仅R41…...

Docker-存储驱动配置

devicemapper驱动devicemapper 是 Linux 内核中的一个框架&#xff0c;它可以将块设备&#xff08;如磁盘、分区、文件&#xff09;映射成虚拟的块设备。Docker 使用它来为每个容器提供一个独立的、隔离的文件系统。 direct-lvm 和 loop-lvm 是 devicemapper 驱动在 Docker 中实…...

【配网可靠性评估】含可再生能源的配电网可靠性评估方法Matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。&#x1f447; 关注我领取海量matlab电子书和数学建模资料&#x1f34a;个人信条&#xff1a;格物致知,完整Matl…...

如何判断提取的RNA是否可用?

在分子生物学实验中&#xff0c;RNA的质量直接决定下游实验的成败。那么&#xff0c;如何科学、系统地评价所提取的RNA是否合格呢&#xff1f;应从浓度、纯度与完整性三个维度综合判断&#xff0c;只有三者均达到标准&#xff0c;才能称为高质量RNA。一、质量评价的三项核心指标…...

Hollander Techniek借助Visual Components仿真平台,打造自动化食品包装系统

荷兰即食餐食供应商Uitgekookt&#xff08;以下简称Uitgekookt&#xff09;计划对其餐食包装流程进行自动化改造&#xff0c;亟需一套能高效、精准处理定制订单的系统。荷兰食品包装自动化集成商HT&#xff08;以下简称HT&#xff09;在实际搭建前&#xff0c;运用Visual Compo…...

AI安全危局:五大实战策略构建企业级防护壁垒

AI安全危局&#xff1a;五大实战策略构建企业级防护壁垒 本文深入解读AI系统安全的五大最佳实践&#xff0c;涵盖治理框架、数据保护、模型防御、供应链安全及持续监控&#xff0c;为企业提供构建纵深防护体系的实战指南。 随着人工智能技术从实验室走向千行百业&#xff0c;AI…...

新企业应该优先选择SEO还是网络推广_SEO和网络推广的具体操作方法有哪些

新企业应该优先选择SEO还是网络推广_SEO和网络推广的具体操作方法有哪些 在数字化营销的时代&#xff0c;新企业在选择推广策略时面临着两大选择&#xff1a;SEO&#xff08;搜索引擎优化&#xff09;和网络推广。两者各有优劣&#xff0c;本文将详细探讨新企业应优先选择哪种…...

Apache Doris存储引擎实战:从LSM-Tree到列式存储的优化技巧

Apache Doris存储引擎实战&#xff1a;从LSM-Tree到列式存储的优化技巧 当你在深夜收到告警&#xff0c;发现Doris集群的写入延迟突然飙升到秒级&#xff1b;当你面对业务方"为什么查询变慢了"的灵魂拷问&#xff0c;却找不到明确原因——这些场景背后&#xff0c;往…...

告别重复编码:用快马AI自动生成数据库增删改查代码,效率提升300%

今天想和大家分享一个提升开发效率的实用技巧——如何用InsCode(快马)平台快速生成数据库相关代码。作为一个经常需要开发库存管理系统的程序员&#xff0c;我发现每次从零开始写数据库模块特别耗时&#xff0c;特别是那些重复的增删改查代码。最近尝试用快马平台后&#xff0c…...

Phi-3-mini-128k-instruct处理复杂数据结构:算法题解答与优化展示

Phi-3-mini-128k-instruct处理复杂数据结构&#xff1a;算法题解答与优化展示 最近在尝试用一些轻量级的模型来辅助解决编程问题&#xff0c;特别是算法和数据结构这块。很多人觉得大模型只能写写简单的脚本&#xff0c;处理复杂逻辑可能不太行。正好手头有Phi-3-mini-128k-in…...