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页面…...

用python中的tkinter包实现进度条
python中的tkinter包是一种常见的设计程序的GUI界面用的包。本文主要介绍这里面的一个组件:进度条(Progressbar)。Tkinter Progressbar里面对进度条组件已经做了一定的介绍,但比较抽象。本文以另一种方式介绍这个组件及其常用用法…...

oneplus3t-lineageos-16.1编译-android9
本仓库开发已经完毕,使用请直接从4.2开始 ** LineageOS16_oneplus3t仓库群克隆 、 编译 、 刷机** 编译过程若ctrlc强制终止,请重新从头编译 LineageOS16_oneplus3t仓库群克隆过程 LineageOS16_oneplus3t仓库群克隆过程描述: LineageOS16_oneplus3t_gitRepoLs_c…...

VSCode+ESP-IDF开发ESP32-S3-DevKitC-1(1)开发环境搭建
VSCodeESP-IDF开发ESP32-S3-DevKitC-1(1)开发环境搭建 1.开发环境搭建(安装ESP-IDF)2.开发环境搭建(安装VS Code)3.开发环境搭建(VSCode中安装ESP-IDF插件及配置) 1.开发环境搭建&am…...

LeetCode --- 143周赛
题目列表 3345. 最小可整除数位乘积 I 3346. 执行操作后元素的最高频率 I 3347. 执行操作后元素的最高频率 II 3348. 最小可整除数位乘积 II 一、最小可整除数位成绩I 由于本题的数据范围比较小,我们直接暴力枚举即可,代码如下 class Solution { p…...

[AI] 【提高认知】自动翻译技术的演变:从规则系统到深度学习的崛起
机器自动翻译 (MT) 是人工智能历史上最早的应用之一,尤其是在英语和俄语之间的翻译应用。自诞生以来,自动翻译技术从符号系统逐步演化到依赖大数据和深度学习的先进模型。本文将深入探讨机器翻译的早期方法、统计方法和现代神经网络方法的演变过程,帮助大家了解自动翻译技术…...

python机器人Agent编程——多Agent框架的底层逻辑(上)
目录 一、前言二、两个核心概念2.1 Routines(1)清晰的Prompt(2)工具调用json schema自动生成(3)解析模型的toolcall指令(4)单Agent的循环决策与输出 PS.扩展阅读ps1.六自由度机器人相…...

渑池县中药材产业党委莅临河南广宇企业管理集团有限公司参观交流
11月14日,渑池县人大副主任、工商联主席杨航率县中药材产业党委代表团一行13人,莅临河南广宇集团参观交流。河南广宇集团总经理王峰、副总经理王培等领导热情接待并陪同参观、座谈。 代表团一行首先参观了集团旗下郑州美信中医院(庚贤堂中医药…...

学习日志011--模块,迭代器与生成器,正则表达式
一、python模块 在之前学习c语言时,我们学了分文件编辑,那么在python中是否存在类似的编写方式?答案是肯定的。python中同样可以实现分文件编辑。甚至还有更多的好处: 提高代码的可维护性:当代码被分成多个文件时…...

ChatGPT 搜索 vs Google 搜索
原文:Amanda Caswell - 2024.11.01 随着 OpenAI 推出的实时搜索功能,ChatGPT 正在逐步成为像 Google 这样的传统搜索引擎的竞争对手。ChatGPT 以其对话式的回答方式而闻名,它能够在没有广告干扰的情况下提供实时的上下文信息。 我迫不及待地…...

一文简单了解Android中的input流程
在 Android 中,输入事件(例如触摸、按键)从硬件传递到应用程序并最终由应用层消费。整个过程涉及多个系统层次,包括硬件层、Linux 内核、Native 层、Framework 层和应用层。我们将深入解析这一流程,并结合代码逐步了解…...