【设计模式】软件设计原则——开闭原则里氏替换单一职责
开闭原则内容引出



开闭原则
定义:一个软件实体,类,函数,模块;对扩展开放,对修改关闭。用抽象构建框架,用实现扩展细节。可以提高软件的可复用性和可维护性。
开发新功能时,尽量不修改原有代码,尽量使用扩展来增加新功能。
实现开闭原则的核心思想是:面向抽象编程,而不是面向实现编程。
定义的对象类型是:抽象or接口;调用的是抽象类or接口中的方法。抽象是稳定的,让一个类依赖于抽象,实现对修改关闭。再通过面向对象的继承与多态,实现对抽象的继承,通过重写方法or实现新的扩展方法。
开闭原则示例
/*** 商品接口*/
public interface IGood {Integer getId();String getName();Double getPrice();
}
/*** 普通商品*/
public class NormalGood implements IGood {private Integer id;private String name;private Double price;public NormalGood(Integer id, String name, Double price) {this.id = id;this.name = name;this.price = price;}@Overridepublic Integer getId() {return this.id;}@Overridepublic String getName() {return this.name;}@Overridepublic Double getPrice() {return this.price;}@Overridepublic String toString() {return "...普通商品信息"}
}
/**
添加打折功能
根据开闭原则 , 对修改关闭 , 对扩展开放;
定义子类,在继承普通商品的基础上,扩展的新功能;
不用实现接口,而是继承普通类。
站在会员卡角度如下:
card接口;普通用户类;银卡继承普通用户;金卡继承银卡
*/
public class DiscountGood extends NormalGood {public DiscountGood(Integer id, String name, Double price) {super(id, name, price);}@Overridepublic Double getPrice() {return super.getPrice() * 0.8;//折扣位置}
}
里氏替换原则
子类可以扩展父类的功能,但不能改变父类原有的功能。
是开闭原则的重要方式之一,由于使用父类对象的地方都可以使用子类对象,因此在程序中尽量使用父类类型来对对象进行定义,而在运行时再确定其子类类型,用子类对象来替换父类对象。
public class FatherClass {public void method(HashMap map) {System.out.println("执行父类 void method(HashMap map) 方法");}
}public class ChildClass extends FatherClass {/*** 重写* 重写 ( 返回值 严格 ) : 当 子类的方法 重写 / 重载 / 实现 父类的方法时* 方法的 后置条件 ( 返回值 ) 要 比父类更严格或相等;*/@Overridepublic void method(HashMap map) {System.out.println("执行子类重写的 void method(HashMap map) 方法");}/*** 重载* 重载 ( 输入参数 宽松 ) : 子类的方法 重载 父类的方法 时* 方法的前置条件 ( 输入参数 ) , 要比 父类方法的输入参数更宽松 ;** 如果在父类中参数类型是 Map* 在子类中重载参数类型是 HashMap* 这样就会出现混乱的问题* 客户端调用时 , 可能不清楚情况 , 加入传入了 HashMap 参数* 此时就有可能出现混乱 , 无法调用到 父类/子类的 正常重写方法* 方法调用被重载方法拦截的情况** 如果 重载的方法 的参数 比父类的方法参数更严格* 那么这就不是重载方法 , 而是重写方法*/public void method(Map map) {System.out.println("执行子类重载的 void method(Map map) 方法");}}
单一职责内容引出

单一职责
定义:不要存在多余一个导致类变更的原因。
假设有一个类,负责“A”和“B”;一旦需求变更,如A功能改变,修改该类A功能时,有可能导致B功能发生故障。对于该情况,应该对于AB各自建立独立的类,保证系统的稳定性。
开发方法:一个类只负责一项职责(类、接口、方法)
优点:可读性高、提高系统可维护性、降低类的复杂度、降低需求变更导致的风险。
模块化的系统中,都适合使用单一职责。
//以下代码均违反了单一职责原则
public class Dog{public void mainDogs(String name) {if ("小狗".equals(name)) {System.out.println("puppy's name is "+name);} else {System.out.println("Dog's name is "+name);}}
}//-----------------------------------------------------------------public class Order {private String orderId;private String userId;private String productId;private double amount;private OrderStatus status;public void createOrder(String userId, String productId, double amount) {// 创建订单 }public void payOrder() {// 支付订单 }public void shipOrder() {// 发货 }public void completeOrder() {// 完成订单 }
}
类的单一
/***本类的职责单一,只负责puppy*/
public class Puppy{public void IsPuppy(String name) {System.out.println("Puppy's name is "+name);}
}
public class Dog{public void IsDog(String name) {System.out.println("Dogs's name is "+name);}
}//--------------------------------------------------
// 订单接口
public interface Order {void create();void pay();void ship();void complete();
}// 创建类
public class OrderCreator implements Order {@Overridepublic void create() {// 创建订单的业务逻辑}
}...其他业务类// 订单完成类
public class OrderCompleter implements Order {@Overridepublic void complete() {
// 完成订单的逻辑}
}
方法单一
如果方法中存在大片的if-else说明是不完善的代码,而我们在开发中其实应该避免如is-else或者switch等条件语句。
//违反单一原则的代码
//如果只针对价格or名字or描述进行修改,会连带修改另外两个,存在一定风险
public class Good {public void updateGoodInfo(String name, double price,String description) {//更新商品信息逻辑}
}//修改后:
public class Good{public void updateGoodName(String Name){//修改名字}public void updateGoodPrice(String Name){//修改价格}public void updateGoodDescription(String Name){//修改商品描述}}
接口单一
public interface IGood {//获取名称String getName();//获取价格double getPrice();//获取商品描述String getDescription();//购买void buyGood();
}//-----------------------拆分------------------------
public interface IGoodInfo{//接口1,商品信息接口String getName();String getDescription();double getPrice();
}public interface IGoodManage{void buyGood();//接口2,商品操作接口//退换等其他逻辑
}//商品实现
publci class IGoodImpl implements IGoodInfo,IGoodManage{@Override//.....
}相关文章:
【设计模式】软件设计原则——开闭原则里氏替换单一职责
开闭原则内容引出 开闭原则 定义:一个软件实体,类,函数,模块;对扩展开放,对修改关闭。用抽象构建框架,用实现扩展细节。可以提高软件的可复用性和可维护性。 开发新功能时,尽量不修…...
项目完整开发的流程
流程 1.设计产品 2.写需求文档 2.1需求分析,后端设计数据库,建表,客户沟通,说完签字,留证据,防止后面扯皮,和防止后续变需求重新写业务 3.画原型图,也就是草图,初始的…...
性能测试学习6:jmeter安装与基本配置/元件/线程组介绍
一.JDK安装 官网:https://www.oracle.com/ 二.Jmeter安装 官网:http://jmeter.apache.org/download_jmeter.cgi 下载zip包,zip后缀那个才是Windows系统的jmeter 三.Jmeter工作目录介绍 四.Jmeter功能 1)修改默认配置-汉化 2&am…...
大数据ETL数据提取转换和加载处理
什么是 ETL? 提取转换加载(英语:Extract, transform, load,简称ETL),用来描述将资料从来源端经过抽取、转置、加载至目的端的过程。ETL一词较常用在数据仓库,但其对象并不限于数据仓库。 ETL&…...
物理与环境安全技术
目录 物理安全 环境安全 物理安全 物理安全是指通过实施一系列的防护措施,以保护人员、设备、设施和信息资源免受物理上的威胁、损坏或非法入侵。 访问控制:限制对数据中心、机房等关键设施的物理访问。通常采用的措施有门禁系统(使用门禁…...
手把手教你如何配置好VS Code的WEB基础开发环境(保姆级)
1. VS Code介绍 微软旗下的多场景开发环境软件,支持JAVA、C、C#、C、WEB、VUE、CSS、HTML、Python等等等 如果你刚刚开始编程或者准备学习WEB,那么我强烈建议你使用这款软件 缺点:(针对初学者) 需要安装各种各样的插…...
高性能、编译器编写语言、编程语言的高低贵贱
高性能 高性能是一个通用名词,可在服务器、客户端甚至浏览器实现高性能。对于大型网站、服务器后端、游戏后端,高性能是一个不可绕过的槛。 高性能技术 池机制 静态分配:就像编译型语言对代码的预处理,不像解释型语言动态解析。可…...
Python安装库时使用国内源pip install -i
普通 安装方式会从国外站点下载, 首先是慢,再有可能会下载失败 所以一般指定国内源 示例 正常情况下,安装pandas这个模块 pip install pandas指定源命令如下: pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ pan…...
Linux 再入门整理:详解 /etc/fstab 文件
目录 1. 什么是 /etc/fstab2. /etc/fstab 文件的格式2.1 设备文件 (Device)2.2 挂载点 (Mount Point)2.3 文件系统类型 (File System Type)2.4 挂载选项 (Mount Options)2.5 Backup Operation(dump 参数)2.6 Pass Order (fsck 参数)2.6.1 参数设置2.6.2 …...
2.8 双绞线、同轴电缆、光纤与无线传输介质
传输介质及分类 传输介质也称为传输媒体,它是发送设备和接收设备之间的物理通路。 传输介质可分为导向传输介质和非导向传输介质。在导向传输介质中,电磁波被导向沿着固体媒介(铜线或光纤)传播,而非导向传输介质可以…...
OBOO鸥柏:布局于为无人机展厅行产业提供LCD液晶显示终端
新华网快讯,于10月9日消息,有投资者在互动平台向OBOO鸥柏公司提问:您好!目前有哪些工业/商用显示产品应用于无人机展厅展馆场景?能否着重介绍下贵司屏幕主要应用哪些品牌无人机数字化展厅展馆做保障? 鸥柏…...
win10状态栏中 “音量” 符号丢失,而在“打开或关闭系统图标”中音量开关无法调节的解决方法
最近在使用电脑需要调节音量时,突然发现电脑右下角的音量图标不见了,在网上搜索了,测试了许多种方法,都没有解决这个问题。 后面想想,使用其他途径,或许可以解决了我的这个问题,终于功夫不负有心…...
Mysql 学习——项目实战
MySQL 学习——项目实战 项目出处 博主:Asmywishi Linux-Ubuntu启动Mysql sudo mysqlData preparation Create Database and Table Create database : create database mysql_example1;Start database : use mysql_example1;Create Student table : # 学生表…...
Springboot 整合 logback 日志框架
文章目录 整合 Logback 日志框架第一步:导入依赖第二步:导入配置(logback.xml)详解 使用(记录日志) 遇到问题一解决方案 整合 Logback 日志框架 第一步:导入依赖 (Springboot 会自己…...
Hugging face简要介绍
1.注册使用huggingface 2.在Datasets下可以查看数据集 3.在Models下可以查看模型,左侧是对模型的分类 4.官方文档查看https://huggingface.co/docs 5.主要模型: 自回归:GPT、Transformer-XL、XLNet 自编码:BERT、ALBERT、RoBERT…...
A股知识答题pk小程序怎么做?
A股知识答题pk小程序怎么做?以下是制作A股知识答题PK小程序的一般步骤: 一、 需求分析与规划: 明确目标:确定小程序的主要目标,比如是为了帮助用户学习A股知识、进行趣味竞赛,还是作为金融教育工具等。 …...
单细胞转录组 —— kb-python 原始数据处理
单细胞转录组 —— kb-python 原始数据处理 前言 kallisto|bustools 是一种用于预处理 scRNA-seq 数据的工作流程。 数据预处理步骤包括: 将 reads 与其来源细胞关联起来;根据唯一分子标识符(UMI)对 reads 进行去重࿱…...
全同态加密算法概览
我们前面有谈到《Paillier半同态加密算法》,半同态加密算法除了支持密文加法运算的 Paillier 算法,还有支持密文乘法计算的 RSA 算法,早期的PSI(隐私求交)和PIR(匿踪查询)都有使用基于RSA盲签名技术来实现。今天我们来谈谈能够有效支持任意函…...
leetcode 刷题day38动态规划Part07 打家劫舍(198.打家劫舍、213.打家劫舍II、337.打家劫舍III)
198.打家劫舍 思路: 1、dp[i]为到第i家偷到的最高金额。 2、如果偷第i家,那么dp[i]dp[i-2]nums[i],如果不偷,则dp[i]dp[i-1],所以递推公式dp[i]max(dp[i-2]nums[i],dp[i-1])。 3、初始值,根据递推公式,我们…...
C0010.Qt5.15.2下载及安装方法
1. 下载及安装 Qt 添加链接描述下载地址:http://download.qt.io/ 选择 archive 目录 安装Qt **注意:**本人使用的是Qt5.15.2版本,可以按如下方法找到该版本;...
观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...
挑战杯推荐项目
“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 - 个性化梦境…...
C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...
YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...
SpringCloudGateway 自定义局部过滤器
场景: 将所有请求转化为同一路径请求(方便穿网配置)在请求头内标识原来路径,然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...
初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...
CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)
漏洞概览 漏洞名称:Apache Flink REST API 任意文件读取漏洞CVE编号:CVE-2020-17519CVSS评分:7.5影响版本:Apache Flink 1.11.0、1.11.1、1.11.2修复版本:≥ 1.11.3 或 ≥ 1.12.0漏洞类型:路径遍历&#x…...
