设计模式六大原则-开放封闭原则(二)
开放封闭原则(Open-Closed Principle, OCP)是设计模式六大原则之一,也是面向对象设计(OOD)中的核心原则之一。它强调软件实体(如类、模块、函数等)应该对扩展开放,对修改封闭。这一原则旨在提高软件的可维护性、可扩展性和灵活性,同时降低因需求变化而导致的修改成本。以下是对开放封闭原则的详细探讨,包括其定义、重要性、实现方法、优点以及在实际应用中的案例。
一、开放封闭原则的定义
开放封闭原则的核心思想是:软件实体(类、模块、函数等)应该能够在不修改现有代码的情况下进行扩展。这意味着当新的需求或变化出现时,我们应该通过添加新的代码来满足这些需求,而不是修改现有的代码。为了实现这一点,我们需要对系统进行抽象化设计,将可能发生变化的部分与稳定的部分分离开来,通过接口、抽象类等机制来定义系统的稳定部分,而将可能发生变化的部分封装在具体的实现类中。
二、开放封闭原则的重要性
开放封闭原则的重要性在于它能够帮助我们构建出更加灵活、可扩展和可维护的软件系统。在软件开发过程中,需求的变化是不可避免的。如果我们的软件系统在设计时没有考虑到这一点,那么每当需求发生变化时,我们都需要对现有的代码进行修改,这不仅会增加开发成本,还会引入新的错误和风险。而遵循开放封闭原则,我们可以将可能发生变化的部分与稳定的部分分离开来,通过扩展新的代码来满足新的需求,从而避免了对现有代码的修改。
三、开放封闭原则的实现方法
- 抽象化设计:对系统进行抽象化设计是实现开放封闭原则的关键。我们需要通过接口、抽象类等机制来定义系统的稳定部分,这些稳定部分不会随着需求的变化而发生变化。同时,我们将可能发生变化的部分封装在具体的实现类中,这些实现类可以根据需求的变化进行扩展和修改。
- 依赖抽象:在编写代码时,我们应该尽量依赖于抽象而不是具体的实现。这意味着我们应该使用接口或抽象类来定义变量类型、参数类型和方法返回类型等,而不是使用具体的实现类。这样做的好处是,当需要扩展新的功能时,我们只需要实现一个新的具体类,并将其注入到系统中即可,而无需修改现有的代码。
- 封装变化:将可能发生变化的部分封装起来是实现开放封闭原则的另一个重要手段。我们可以将可能发生变化的状态、行为或数据封装在一个类中,并通过接口或抽象类来提供对这些变化的访问。这样,当这些变化发生时,我们只需要修改这个封装类即可,而无需修改其他部分的代码。
四、开放封闭原则的优点
- 提高软件的可维护性:由于软件实体对扩展开放、对修改封闭,因此当需求发生变化时,我们只需要添加新的代码来满足这些变化,而无需修改现有的代码。这大大降低了软件维护的难度和成本。
- 提高软件的可扩展性:通过抽象化设计和依赖抽象,我们可以轻松地扩展新的功能,而无需对现有代码进行任何修改。这使得软件系统能够灵活地应对未来的需求变化。
- 提高软件的可复用性:遵循开放封闭原则设计的软件系统具有更高的可复用性。因为系统中的稳定部分(如接口、抽象类等)可以被多个不同的实现类所共享和复用。
- 降低耦合度:通过依赖抽象而不是具体的实现,我们可以降低软件实体之间的耦合度。这使得软件系统更加灵活和易于修改。
五、实际应用案例
假设我们正在开发一个在线购物系统,该系统需要支持多种支付方式(如支付宝、微信支付、银行卡支付等)。如果我们不遵循开放封闭原则,我们可能会在支付模块中直接编写针对每种支付方式的代码。然而,当新的支付方式出现时,我们就需要修改支付模块的代码来添加对这种新支付方式的支持。这不仅会增加开发成本,还会引入新的错误和风险。
为了遵循开放封闭原则,我们可以采用以下设计方案:
- 定义支付接口:首先,我们定义一个支付接口(如
IPayment),该接口中包含了支付所需的所有方法(如pay方法)。 - 实现具体支付类:然后,我们针对每种支付方式实现一个具体的支付类(如
AlipayPayment、WechatPayment、BankCardPayment等),这些类都实现了IPayment接口。 - 支付模块依赖抽象:在支付模块中,我们不再直接编写针对每种支付方式的代码,而是依赖于
IPayment接口。当需要执行支付操作时,我们只需要调用IPayment接口的pay方法即可。至于具体使用哪种支付方式,则由客户端在运行时决定,并通过依赖注入的方式将具体的支付类注入到支付模块中。
通过这种方式,当新的支付方式出现时,我们只需要实现一个新的支付类,并将其注入到支付模块中即可,而无需修改现有的代码。这完全符合开放封闭原则的要求。
相关文章:
设计模式六大原则-开放封闭原则(二)
开放封闭原则(Open-Closed Principle, OCP)是设计模式六大原则之一,也是面向对象设计(OOD)中的核心原则之一。它强调软件实体(如类、模块、函数等)应该对扩展开放,对修改封闭。这一原…...
C# 截取两个点之间的线段,等距分割线
//取线段上两点之间的沿线线段//line 线//startDist:距离线第一个点的起点位置//stopDist:距离线第一个点的终点位置public static List<double[]> lineSliceAlong(List<double[]> line, double startDist, double stopDist){double travelled 0;double overshot …...
打造聊天流式回复效果:Spring Boot+WebSocket + JS实战
本篇博客将带领你使用 Spring Boot、WebSocket 和 JavaScript 实现一个类似 ChatGPT 的流式回复效果。前端发送消息后,后端接收消息并请求 AI API,并将 AI 返回的流式响应实时推送到前端,最终在聊天界面呈现出逐字出现的打字效果。 技术原理…...
202年版最新Python下载安装+PyCharm下载安装激活和使用教程!(附安装包+激活码)
一、Python解释器下载【运行环境】 Python官网: https://www.python.org Python各版本解释器官网: https://www.python.org/downloads/ 二、Windows系统安装Python解释器 下载Python版本解释器 现在已经更新到了3.13版本的Python解释器,但…...
【面试宝典】spring常见面试题总结[上]
一、什么是 Spring 框架? Spring 框架是一个为 Java 应用程序的开发提供了综合、广泛的基础性支持的 Java 平台。 Spring 帮助开发者解决基础性的问题,使开发者专注编写业务代码。 二、Spring Freamework 有哪些功能? IOC: 控制反转AOP: 面…...
NC单链表的排序
系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。 描述 给定一个节点…...
阿里云部署open-webui实现openai代理服务(持续更新)
一、展示 xiezhaoxuan.top:8080 二、 环境准备 1. 阿里云服务器,ubuntu22系统 2. http代理(可访问外网) 3. openai API Key 三、实际操作记录(阿里云服务器端) 1. 根据官方文档安装open-webui服务端(看完这节再操作): 🚀 Getting Started | Open WebUI 1. 如果服务器配置比较…...
Vue3简介和快速体验
文章目录 前言1. Vue3介绍2. Vue3快速体验(非工程化方式) 前言 本次主要用VScode开发代码,vscode的安装很简单,不会的可以查询一下网上的资料 1. Vue3介绍 Vue (发音为 /vjuː/,类似 view) 是一款用于构建用户界面的 JavaScript 框架。它基于…...
LeetCode98 验证二叉搜索树
前言 题目: 98. 验证二叉搜索树 文档: 代码随想录——验证二叉搜索树 编程语言: C 解题状态: 对中序遍历理解不到位 思路 了解了中序遍历会返回一个有序数组后,本题就可以迎刃而解。只需要判断,返回的数组…...
llama的神经网络结构;llama的神经网络结构中没有MLP吗;nanogpt的神经网络结构;残差是什么;残差连接:主要梯度消失
目录 解释代码 潜在问题和修正 结论 llama的神经网络结构 神经网络结构概述 举例说明 llama的神经网络结构中没有MLP吗 nanogpt的神经网络结构 1. 词嵌入层(Embedding Layer) 2. Transformer编码器层(Transformer Encoder Layer) 3. 层归一化(Layer Normalizat…...
函数的常量引用入参const saclass sdf,可否传入一个指向saclass对象的指针 shared_ptr<saclass>
不可以直接将一个指向 saclass 对象的 shared_ptr<saclass> 作为参数直接传入一个期望 const saclass& 类型参数的函数。原因是类型不匹配:shared_ptr<saclass> 是一个智能指针类型,它封装了对 saclass 对象的指针,并提供了一…...
数据库:SQL——数据库操作的核心语言
数据库:SQL——数据库操作的核心语言 SQL(结构化查询语言)是关系型数据库管理系统中的标准语言,广泛用于数据的定义、操作、控制和查询。SQL 包含多个子语言,分别用于不同的数据库操作任务,包括数据定义&a…...
Unity + HybridCLR 从零开始
官方文档开始学习,快速上手 | HybridCLR (code-philosophy.com)是官方文档链接 1.建议使用2019.4.40、2020.3.26、 2021.3.0、2022.3.0 中任一版本至于其他2019-2022LTS版本可能出现打包失败情况 2. Windows Win下需要安装visual studio 2019或更高版本。安装时至少要包含 使…...
C++小总结
C小总结 接口 对外暴露头文件中,只需要声明接口函数即可,其他不暴露的函数不需要进行声明。接口的参数使用指针形式比较好,因为外部使用时可以对实参进行创建和析构,如果非接口函数使用new开辟,不太好进行析构。在使…...
从快到慢学习Git指令
Git是现在最流行的版本控制工具之一。无论是在开源社区还是企业软件开发中,Git都扮演着至关重要的角色。本文将根据不同的需求,分别提供快速上手和深入学习Git的指南。 如果你只想下载代码 如果你只是想下载GitHub或其他代码仓库的代码,那你只需要了解以下两个命令: git clo…...
传奇游戏发布渠道
传奇游戏发布渠道 回答:游戏发布平台|手机游戏发布平台 传奇游戏发布渠道作为游戏开发商直接控制的信息传播途径,其安全性自然有着较高的保障。首先,渠道通常会采用先进的加密技术和安全协议来保护数据传输过程中的安全,防止信息…...
如何有效阅读科研论文【方法论】
如何读论文【论文精读1】_哔哩哔哩_bilibili 如何有效阅读科研论文 科研论文是了解学术领域最新研究成果和技术发展的重要途径。有效地阅读论文不仅能够帮助我们掌握前沿知识,还能提升自己的研究能力。本文将介绍一种系统的论文阅读方法,并通过具体的步…...
【揭秘】层层加码,竟能加速渠道营销数字化?-eBest
国潮饮料品牌在eBest RTM系统的支持下,已经将数字化贯彻到每一个销售环节,且看eBest如何通过“层层加码”,进一步加速该饮料品牌渠道数字化进程,实现弯道超车? “一箱四码”垛码 五码实现渠道数字化 为提高营销和数字…...
基于WAMP环境的简单用户登录系统实现(v3版)(持续迭代)
目录 版本说明 实现环境: 流程逻辑框图: 数据库连接 登录页面:login.html 登录处理实现:doLogin.php 用户欢迎页面:welcome.php 密码修改页面:change_password.html 修改处理:doChangePa…...
大语言模型与多模态大模型loss计算
文章目录 前言一、大语言模型loss计算1、loss计算代码解读2、构建模型输入内容与label标签3、input_ids与labels格式 二、多模态大模型loss计算方法1、多模态loss计算代码解读2、多模态输入内容2、大语言模型输入内容3、图像embending如何嵌入文本embeding 前言 如果看了我前面…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...
盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...
Spring Boot 实现流式响应(兼容 2.7.x)
在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE) 或 流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会…...
QMC5883L的驱动
简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...
P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...
【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)
升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求ÿ…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...
