设计模式六大原则-开放封闭原则(二)
开放封闭原则(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 前言 如果看了我前面…...
IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...
盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...
STM32F4基本定时器使用和原理详解
STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...
微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...
LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
【JVM面试篇】高频八股汇总——类加载和类加载器
目录 1. 讲一下类加载过程? 2. Java创建对象的过程? 3. 对象的生命周期? 4. 类加载器有哪些? 5. 双亲委派模型的作用(好处)? 6. 讲一下类的加载和双亲委派原则? 7. 双亲委派模…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能
1. 开发环境准备 安装DevEco Studio 3.1: 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK 项目配置: // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...
