设计模式六大原则-开放封闭原则(二)
开放封闭原则(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 前言 如果看了我前面…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...
超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
uniapp微信小程序视频实时流+pc端预览方案
方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度WebSocket图片帧定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐RTMP推流TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...
Java + Spring Boot + Mybatis 实现批量插入
在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法:使用 MyBatis 的 <foreach> 标签和批处理模式(ExecutorType.BATCH)。 方法一:使用 XML 的 <foreach> 标签ÿ…...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...
七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...
MySQL的pymysql操作
本章是MySQL的最后一章,MySQL到此完结,下一站Hadoop!!! 这章很简单,完整代码在最后,详细讲解之前python课程里面也有,感兴趣的可以往前找一下 一、查询操作 我们需要打开pycharm …...
