1 设计模式原则之开闭原则
一、开闭原则
1.定义
开闭原则:对扩展开放,对修改关闭。
2.具体用法
在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。简言之,是为了使程序的扩展性好,易于维护和升级。
想要达到这样的效果,我们需要使用接口和抽象类。
因为抽象灵活性好,适应性广,只要抽象的合理,可以基本保持软件架构的稳定。而软件中易变的细节可以从抽象派生来的实现类来进行扩展,当软件需要发生变化时,只需要根据需求重新派生一个实现类来扩展就可以了。
3.代码举例
public class Client {public static void main(String[] args) {//创建搜狗输入法SouGouInput souGouInput = new SouGouInput();//创建皮肤对象DefaultSkin defaultSkin = new DefaultSkin();//将皮肤设置到输入法souGouInput.setSkin(defaultSkin);//显示皮肤souGouInput.display();}
}public abstract class AbstractSkin {//显示的方法public abstract void display();
}public class DefaultSkin extends AbstractSkin{public void display(){System.out.println("默认皮肤 ");}}public class CSDNSkin extends AbstractSkin{@Overridepublic void display() {System.out.println("欢迎使用Theodore的皮肤!");}
}public class SouGouInput {private AbstractSkin skin;public void setSkin(AbstractSkin skin) {this.skin = skin;}public void display(){skin.display();}
}
4.案例讲解
(1)抽象类 AbstractSkin
:为扩展皮肤做好准备
public abstract class AbstractSkin { public abstract void display();
}
- 这是一个 抽象类,定义了一个抽象方法
display()
,用来显示皮肤。 - 为什么要这样设计?
- 这样做的目的是:为未来新增不同的皮肤提供扩展能力。只要继承这个抽象类并实现
display
方法,就可以定义新的皮肤。
- 这样做的目的是:为未来新增不同的皮肤提供扩展能力。只要继承这个抽象类并实现
- 开闭原则体现:
- 对扩展开放:未来我们可以新增任何皮肤类,而不需要修改
AbstractSkin
类本身。 - 对修改关闭:无需修改
AbstractSkin
类的代码,只需要新增子类实现新的功能。
- 对扩展开放:未来我们可以新增任何皮肤类,而不需要修改
(2)具体皮肤类 DefaultSkin
和 CSDNSkin
:通过扩展实现新功能
public class DefaultSkin extends AbstractSkin { public void display() { System.out.println("默认皮肤"); }
}
public class CSDNSkin extends AbstractSkin { @Override public void display() { System.out.println("欢迎使用Theodore的皮肤!"); }
}
- 这里我们定义了两个具体的皮肤类,分别是默认皮肤和 CSDN 皮肤。
- 开闭原则体现:
- 对扩展开放:如果以后你想新增一个皮肤,比如说 “暗黑皮肤”,只需要新建一个
DarkModeSkin
类,继承AbstractSkin
,并实现display
方法。 - 对修改关闭:你无需修改
DefaultSkin
和CSDNSkin
的代码,就可以新增新的皮肤类。
- 对扩展开放:如果以后你想新增一个皮肤,比如说 “暗黑皮肤”,只需要新建一个
(3)输入法类 SouGouInput
:通过抽象类实现扩展性
public class SouGouInput {private AbstractSkin skin; // 依赖于抽象类public void setSkin(AbstractSkin skin) {this.skin = skin;}public void display() {skin.display();}
}
SouGouInput
类表示搜狗输入法,它并不知道有哪些具体皮肤,只知道这些皮肤都是AbstractSkin
的子类。- 开闭原则体现:
- 对扩展开放:你可以传入任何
AbstractSkin
的子类,比如DefaultSkin
、CSDNSkin
或未来的DarkModeSkin
。 - 对修改关闭:
SouGouInput
类的代码并不需要因为新增了新皮肤而进行任何修改。
- 对扩展开放:你可以传入任何
(4)客户端类 Client
:使用不同皮肤而不改动输入法
public class Client {public static void main(String[] args) {SouGouInput souGouInput = new SouGouInput();// 使用默认皮肤souGouInput.setSkin(new DefaultSkin());souGouInput.display();// 切换到 CSDN 皮肤souGouInput.setSkin(new CSDNSkin());souGouInput.display();}
}
输出结果:
默认皮肤 欢迎使用Theodore的皮肤!
- 开闭原则体现:
- 在客户端中,
SouGouInput
可以使用任意的皮肤,而无需修改SouGouInput
类的核心逻辑。 - 如果想新增一个皮肤,比如暗黑皮肤,只需要这样写:
新增的皮肤功能可以被无缝集成,而无需对已有代码做出修改。souGouInput.setSkin(new DarkModeSkin()); souGouInput.display();
- 在客户端中,
5.总结
通过这个例子,我们可以看到,开闭原则 是如何帮助我们设计出 灵活且易于扩展 的代码结构:
- 抽象类
AbstractSkin
提供扩展点:所有新皮肤都通过继承这个类来扩展功能。 SouGouInput
类依赖抽象类,而不是具体实现:这让输入法系统无需修改现有代码即可使用新的皮肤。- 新增功能不改动现有代码:新增皮肤只需创建新的子类,不需要修改
SouGouInput
和已有的皮肤类。
这样,我们既能满足用户不断变化的需求(比如新增不同风格的皮肤),又能保证现有代码的稳定性,减少修改代码引入错误的风险。
相关文章:
1 设计模式原则之开闭原则
一、开闭原则 1.定义 开闭原则:对扩展开放,对修改关闭。 2.具体用法 在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。简言之,是为了使程序的扩展性好,易于维护和升级。 想要达到这…...
前端大环境
需求增长: 数字化转型推动:企业和组织的数字化转型进程不断加快,对前端开发的需求持续增加。无论是企业官网、电子商务平台、在线办公系统还是各种移动端应用,都需要专业的前端开发来打造良好的用户界面和交互体验。新兴技术和平台…...
Electron: 主进程和渲染进程之间通信
// 渲染进程 向 主进程 异步通信// preload.js 预加载 const {ipcRenderer} require(electron) ipcRenderer.send(on-send-event, 这里是需要传递的参数) // 第一步ipcRenderer.on(on-resend-event, (e, data) > {console.log(data) // 打印的是ipcMain.on传递过来的参数&a…...

社交电商的优势及其与 AI 智能名片小程序、S2B2C 商城系统的融合发展
摘要:本文深入分析了社交电商相较于传统电商的优势,包括门槛低、易操作、更生活化和可团队化运作等特点。同时,探讨了 AI 智能名片小程序和 S2B2C 商城系统在社交电商发展中的作用,以及它们与社交电商融合所带来的新机遇和发展前景…...

蓝桥杯c++算法学习【4】之简单数论(阶乘约数、求值、循环小数、等差数列、最大比例:::非常典型的必刷例题!!!)
别忘了请点个赞收藏关注支持一下博主喵!!!! 关注博主,更多蓝桥杯nice题目静待更新:) 简单数论 一、阶乘约数 【问题描述】 定义阶乘n!123...n。 请问100! (100 的阶乘)有多少个正约数。 【答案提交】 这…...
重构代码之删除对参数的赋值
删除对参数的赋值 是一种重构技术,旨在消除对方法参数的重新赋值。这种实践可以增强代码的可读性和维护性,避免潜在的副作用。以下是详细讲解: 一、动机 保护参数的意图:方法参数通常表示传入数据或状态。如果重新赋值ÿ…...
Docker的基本概念、安装步骤以及一些简单的用法
Docker 是一种开源的容器化平台,允许开发者打包应用及其依赖项到一个可移植的容器中。容器可以在任何支持Docker的环境中运行,这使得应用的部署和管理变得更加简单和高效。 1. Docker的基本概念 在深入学习Docker之前,了解一些基本概念是很…...

VuePress v2 快速搭建属于自己的个人博客网站
目录 为什么用VuePress? 一、前期准备 Node.js 使用主题快速开发 二、VuePress安装 三、个性化定制 修改配置信息 删除不需要的信息 博客上传 四、部署 使用github快速部署 初始化仓库 本地配置 配置github的ssh密钥 部署 为什么用VuePressÿ…...

shell编程--永久环境变量和字符串显位
环境变量 echo $HOME 在终端输出后会显示家目录有个root变量 我们会提出个疑问为什么平时我们在终端输入sl 或者which等等命令会输出一些内容呢,这是因为这些命令都有对应的环境变量。 我们查看一下环境变量 在终端输入: echo $PATH 我们看一下输出…...

【优选算法篇】算法江湖中的碎玉拾光——C++模拟题全解,踏步逐章细细品味
文章目录 C 模拟题详解:基础题解与细致分析前言第一章:基础练习1.1 替换所有的问号(easy)解法(模拟)C 代码实现易错点提示时间复杂度和空间复杂度 1.2 提莫攻击(easy)解法࿰…...

【MySQL 保姆级教学】事务的隔离级别(详细)--下(14)
事务的隔离级别 1. 如何理解事务的隔离性2. 事务隔离级别的分类3. 查看和设置事务隔离级别3.1 全局和会话隔离级别3.2 查看和设置隔离级别 4. 事务隔离级别的演示4.1 读未提交(Read Uncommitted)4.2 读已提交(Read Committed)4.3 …...
部分利用oracle数据字典查询对应信息的语句。
查看当前用户的缺省表空间 SQL>select username,default_tablespace from user_users; 查看当前用户的角色 SQL>select * from user_role_privs; 查看当前用户的系统权限和表级权限 SQL>select * from user_sys_privs; SQL>select * from user_tab_privs; …...

实例教程:BBDB为AHRS算法开发提供完善的支撑环境(上)
1. 概述 本教程将结合程序代码及CSS控制站工程,讲述如何基于PH47代码框架的BBDB固件版本,为开发自己的AHRS姿态解算算法提供完善支撑环境,以及数据分析手段。 BBDB固件已内置了一套姿态解算算法。对于需要进行AHRS算法开发研究的开发者&…...
k8s搭建1.23版本
文章目录 1、前期准备1、关闭防火墙和selinux2、关闭交换分区3、修改主机名和免密登录4、内核参数5、安装docker6、安装k8s源 2、安装1、安装k8s软件包2、初始化k8s3、安装calico网络插件4、检查 1、前期准备 以下操作所有主机都要运行的 1、关闭防火墙和selinux systemctl …...

【MYSQL】分库分表
一、什么是分库分表 分库分表就是指在一个数据库在存储数据过大,或者一个表存储数据过多的情况下,为了提高数据存储的可持续性,查询数据的性能而进行的将单一库或者表分成多个库,表使用。 二、为什么要分库分表 分库分表其实是两…...

CSS基础知识05(弹性盒子、布局详解,动画,3D转换,calc)
目录 0、弹性盒子、布局 0.1.弹性盒子的基本概念 0.2.弹性盒子的主轴和交叉轴 0.3.弹性盒子的属性 flex-direction row row-reverse column column-reverse flex-wrap nowrap wrap wrap-reverse flex-dirction和flex-wrap的组合简写模式 justify-content flex-s…...
常见error集合
Cannot use import statement outside a module 原因:在commonJS中用了es6的语法,import。分析: 一般我们的运行环境按照模块化标准来分,可以分为es6和commonJS两种,在es6中引入模块用import,在commonJS中…...
建筑施工特种作业人员安全生产知识试题
1.因生产安全事故受损害的从业人员,除依法享有工伤社会保验外。依照有关民事法律尚有获得赔偿的权利,有权向本单位提出(D)。 A.任何要求 B.保护要求 C.辞职要求 D.赔偿要求 2.为了加强建设工程安全监督管理&…...

2024140读书笔记|《作家榜名著:生如夏花·泰戈尔经典诗选》——你从世界的生命的溪流浮泛而下,终于停泊在我的心头
2024140读书笔记|《作家榜名著:生如夏花泰戈尔经典诗选》——你从世界的生命的溪流浮泛而下,终于停泊在我的心头 《作家榜名著:生如夏花泰戈尔经典诗选》[印]泰戈尔,郑振铎译,泰戈尔的诗有的清丽,有的童真&…...
JSP是如何被执行的?
JSP(JavaServer Pages)是一种用于构建动态Web页面的技术,它允许开发者在HTML、XML或其他文本格式的文档中嵌入Java代码。JSP页面在服务器端被编译成Servlet,然后由Servlet容器(如Tomcat)执行。以下是JSP页面…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...

【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器
——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的一体化测试平台,覆盖应用全生命周期测试需求,主要提供五大核心能力: 测试类型检测目标关键指标功能体验基…...

Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...
拉力测试cuda pytorch 把 4070显卡拉满
import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

三分算法与DeepSeek辅助证明是单峰函数
前置 单峰函数有唯一的最大值,最大值左侧的数值严格单调递增,最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值,最小值左侧的数值严格单调递减,最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...
MinIO Docker 部署:仅开放一个端口
MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...

MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)
macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 🍺 最新版brew安装慢到怀疑人生?别怕,教你轻松起飞! 最近Homebrew更新至最新版,每次执行 brew 命令时都会自动从官方地址 https://formulae.…...