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)具体皮肤类 DefaultSkinCSDNSkin:通过扩展实现新功能

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 方法。
    • 对修改关闭:你无需修改 DefaultSkinCSDNSkin 的代码,就可以新增新的皮肤类。

(3)输入法类 SouGouInput:通过抽象类实现扩展性

public class SouGouInput {private AbstractSkin skin; // 依赖于抽象类public void setSkin(AbstractSkin skin) {this.skin = skin;}public void display() {skin.display();}
}
  • SouGouInput 类表示搜狗输入法,它并不知道有哪些具体皮肤,只知道这些皮肤都是 AbstractSkin 的子类。
  • 开闭原则体现
    • 对扩展开放:你可以传入任何 AbstractSkin 的子类,比如 DefaultSkinCSDNSkin 或未来的 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.总结

通过这个例子,我们可以看到,开闭原则 是如何帮助我们设计出 灵活且易于扩展 的代码结构:

  1. 抽象类 AbstractSkin 提供扩展点:所有新皮肤都通过继承这个类来扩展功能。
  2. SouGouInput 类依赖抽象类,而不是具体实现:这让输入法系统无需修改现有代码即可使用新的皮肤。
  3. 新增功能不改动现有代码:新增皮肤只需创建新的子类,不需要修改 SouGouInput 和已有的皮肤类。

这样,我们既能满足用户不断变化的需求(比如新增不同风格的皮肤),又能保证现有代码的稳定性,减少修改代码引入错误的风险。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/473526.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

aws中AcmClient.describeCertificate返回值中没有ResourceRecord

我有一个需求,就是让用户自己把自己的域名绑定我们的提供的AWS服务器。 AWS需要验证证书 上一篇文章中我用php的AcmClient中的requestCertificate方法申请到了证书。 $acmClient new AcmClient([region > us-east-1,version > 2015-12-08,credentials>[/…

Oracle 19c PDB克隆后出现Warning: PDB altered with errors受限模式处理

在进行一次19c PDB克隆过程中,发现克隆结束,在打开后出现了报错,PDB变成受限模式,以下是分析处理过程 09:25:48 SQL> alter pluggable database test1113 open instancesall; Warning: PDB altered with errors. Elapsed: 0…

【3D Slicer】的小白入门使用指南九

定量医学影像临床研究与实践 任务 定量成像教程 定量成像是从医学影像中提取定量测量的过程。 本教程基于两个定量成像的例子构建: - 形态学:缓慢生长肿瘤中的小体积变化 - 功能:鳞状细胞癌中的代谢活动 第1部分:使用变化跟踪模块测量脑膜瘤的小体积变化第2部分:使用PET标…

二、神经网络基础与搭建

神经网络基础 前言一、神经网络1.1 基本概念1.2 工作原理 二、激活函数2.1 sigmoid激活函数2.1.1 公式2.1.2 注意事项 2.2 tanh激活函数2.2.1 公式2.2.2 注意事项 2.3 ReLU激活函数2.3.1 公式2.3.2 注意事项 2.4 SoftMax激活函数2.4.1 公式2.4.2 Softmax的性质2.4.3 Softmax的应…

VMWare虚拟机安装华为欧拉系统

记录一下安装步骤: 1.在vmware中创建一个新的虚拟机,步骤和创建centos差不多 2.启动系统 具体的看下图: 启动虚拟机 耐心等待 等待进度条走完重启系统就完成了

如何进入python交互界面

Python交互模式有两种:图形化的交互模式或者命令行的交互模式。 打开步骤: 首先点击开始菜单。 然后在搜索栏中输入Python,即可看到图形化的交互模式(IDLE(Python 3.7 64-bit))与命令行的交互…

NVR录像机汇聚管理EasyNVR多品牌NVR管理工具视频汇聚技术在智慧安防监控中的应用与优势

随着信息技术的快速发展和数字化时代的到来,安防监控领域也在不断进行技术创新和突破。NVR管理平台EasyNVR作为视频汇聚技术的领先者,凭借其强大的视频处理、汇聚与融合能力,展现出了在安防监控领域巨大的应用潜力和价值。本文将详细介绍Easy…

【STM32】USB 简要驱动软件架构图

STM32 USB 软件架构比较复杂,建议去看 UM 1734 或者 st wiki STM32 USB call graph STM32 USB Device Library files organization Reference [1]: https://wiki.stmicroelectronics.cn/stm32mcu/wiki/Introduction_to_USB_with_STM32 [2]: UM1734

高翔【自动驾驶与机器人中的SLAM技术】学习笔记(十三)图优化SLAM的本质

一、直白解释slam与图优化的结合 我从b站上学习理解的这个概念。 视频的大概位置是1个小时以后,在第75min到80min之间。图优化SLAM是怎么一回事。 slam本身是有运动方程的,也就是运动状态递推方程,也就是预测过程。通过t1时刻&#xff0c…

Vue2教程002:Vue指令

文章目录 2、Vue指令2.1 开发者工具2.2 v-html2.3 v-show和v-if2.4 v-else和v-else-if2.5 v-on2.5.1 内联语句2.5.2 methods 2、Vue指令 2.1 开发者工具 通过谷歌应用商店安装(需要科学上网)通过极简插件安装 2.2 v-html Vue会根据不同的指令&#x…

使用WebSocket技术实现Web应用中的实时数据更新

💓 博客主页:瑕疵的CSDN主页 📝 Gitee主页:瑕疵的gitee主页 ⏩ 文章专栏:《热点资讯》 使用WebSocket技术实现Web应用中的实时数据更新 使用WebSocket技术实现Web应用中的实时数据更新 使用WebSocket技术实现Web应用中…

单片机学习笔记 1. 点亮一个LED灯

把基础的东西都过一下,用来学习记录一下。 目录 1、Keil工程 2、Keil实现代码 3、烧录程序 0、实现的功能 点亮一个LED灯 1、Keil工程 打开Keil,Project----New uVision Project,工程文件命名----OK 选择单片机类型AT89C52,和…

使用Web Animations API实现复杂的网页动画效果

💓 博客主页:瑕疵的CSDN主页 📝 Gitee主页:瑕疵的gitee主页 ⏩ 文章专栏:《热点资讯》 使用Web Animations API实现复杂的网页动画效果 使用Web Animations API实现复杂的网页动画效果 使用Web Animations API实现复杂…

计算机组成与原理(2) basic of computer architecture

Instruction Set Architecture (ISA) 和 Hardware System Architecture (HSA) 是计算机体系结构中两个重要的层次,它们各自的职责和作用如下: Instruction Set Architecture (ISA) 定义 ISA是指令集体系结构,是硬件和软件之间的接口。它定义…

Python Excel XLS或XLSX转PDF详解:七大实用转换设置

目录 使用工具 Python将Excel文件转换为PDF Python将Excel文件转换为带页码的PDF Python将Excel文件转换为特定页面尺寸的PDF Python将Excel文件转换为PDF并将内容适应到一页 Python将Excel文件转换为PDF/A Python将Excel文件中的工作表转换为单独的PDF Python将Excel工…

【C++】红黑树封装map—set

1 .关联式容器 C中的map是标准模板库(STL)中的一种关联容器,它存储的是键值对(key-value pairs),其中每个键都是唯一的。 键值对: 用来表示具有一一对应关系的一种结构,该结构中一…

系统思考—结构影响行为

最近在和一些企业领导者交流时,发现一个共性——创始人都非常厉害!战略清晰、点子多、方向准,简直就是企业的“定海神针”。但往往问题在了下一层级:如何把创始人的智慧传承下去,甚至复制到团队里,这成了一…

定时器简介

TIM(Timer定时器)简介 在第一部分,我们主要讲的是定时器基本定时的功能,也就是定一个时间,然后让定时器每隔这个时间产生一个中断,来实现每隔一个固定时间执行一段程序的目的,比如你要做个时钟、秒表,或者使用一些程序…

快排和归并

目录 前言 快速排序 相遇位置一定比key小的原理(大): 避免效率降低方法(快排优化) 三数取中(选key优化) 小区间优化 hoare版本快排 挖坑法快排 前后指针快排 非递归快排 归并排序 非递…

代码段数据段的划分

DPL DPL存储在段描述符中,规定访问该段的权限级别(Descriptor Privilege Level) CPL CPL是当前进程的权限级别(Current Privilege Level),是当前正在指向的代码段所在段的成绩,也就是CS段的DPL RPL RPL说明的是进程对段访问的请求权限(Re…