趣解设计模式之《我买了宝马,为啥不让我停这?》
〇、小故事
我们怎么识别一辆汽车是宝马品牌的汽车呢?虽然宝马汽车车辆型号非常的多,而且外型也各不相同,但是只要是宝马品牌的汽车,它的车头一定会有宝马汽车的logo,那么这个就是大家最直观去确认一辆车是不是宝马牌汽车的主要依据了。

所以,宝马公司就跟各地负责宝马专属停车位的保安和管理人员们说,只允许车头有宝马logo的汽车进入BMW的免费停车场。

话说小王同学,她努力工作了一段时间,终于决定在自己的26岁生日时,买了一辆宝马车作为送给自己的礼物。

但是,过了一段时间,她的一个小姐妹买了一辆保时捷,她瞬间爱上了保时捷品牌,但是那个车子太贵了,自己根本买不起的,为了圆梦保时捷,她做了一个“大胆”的决定,把车头宝马的logo扣掉换上了保时捷的logo。她看到自己的车子也是保时捷了,心中那种满足感油然而生。
但是,当有一次她要出差去机场,知道飞机场有宝马的免费停车位,她高高兴兴的就开车过去了,但是保安大爷说什么都不让她开进去,虽然她的车子的确是宝马汽车,但是车子的logo却不是宝马的,成为了一辆“四不像”汽车……
一、原则定义
通过上面的例子,我们可以看到小王遇到的问题就是,自己的车标不是宝马车标,所以不符合宝马公司允许停车的标准了。那么,我们可以这样认为:
【宝马汽车】是父类,它有一个方法是
getLogo(),这个方法会返回BMW;
【3系、X3、5系、7系……】是子类,继承了父类的getLogo(),调用后也会返回BMW;
所以宝马公司就有理由决定,只要调用getLogo()方法且返回“BMW”的车子,都可以被认为是宝马汽车,那么自然而然可以通过这个条件,来限制哪些车辆可以免费停到BMW的专属车位了。而小王自己把方法getLogo()进行了修改,使得这个方法返回了Porsche,造成了原本是宝马车却无法停到BMW专属车位的系统异常。
了解了上面的故事,我们来真正的学习一下里式替换,它是什么含义:
LSP(
Liskov Substitution Principle):子类对象能够替换父类对象,而程序逻辑不变。继承必须确保父类所拥有的性质在子类中仍然成立。也可以理解为:子类可以扩展父类的功能,但不能改变父类原有的功能,建议多用组合,少用继承。
那么,此处也会有同学疑惑,“多用组合,少用继承”这个不应该是合成复用原则吗?如果我们是针对7种设计原则的维度来说,这个是没错的。如果我们针对6种设计模式来说,是不包含合成复用原则的,而“多用组合,少用继承”就被包含在了里式替换中,作为里式替换原理之后的一种编码建议。
二、原则实践
上面的故事和原理相信大家都已经有所了解了,我们还是举一个业务上的小例子,再来加深说明一下违反里式替换后可能会出现的问题。
业务背景:
【1】在一个父类
Pay中,存在一个通用方法execute(),该方法是用于执行某项通用的业务操作;
【2】然后,针对这个父类A我们继承了多个子类,分别是AlibabaPayImpl、WechatPayImpl、JDPayImpl……
【3】此时呢,我们违反了LSP原则,将JDPayImpl类中的execute()方法进行了自定义,但是对于父类Pay来说,它是不知道的。
【4】那么,过了一段时间,公司这边说,需要在execute()方法的业务上加上某些规则校验,那么由于子类都继承了这个方法,所以开发人家就只需要在Pay类的execute()方法上添加这些规则校验,所有的子类就都同时拥有了这种规则校验了。
【5】但是,由于JDPayImpl自己实现了父类的execute()方法,所以它没有继承规则校验功能,系统出现了漏洞……
今天的文章内容就这些了:
写作不易,笔者几个小时甚至数天完成的一篇文章,只愿换来您几秒钟的 点赞 & 分享 。
更多技术干货,欢迎大家关注公众号“爪哇缪斯” ~ \(^o^)/ ~ 「干货分享,每天更新」
相关文章:
趣解设计模式之《我买了宝马,为啥不让我停这?》
〇、小故事 我们怎么识别一辆汽车是宝马品牌的汽车呢?虽然宝马汽车车辆型号非常的多,而且外型也各不相同,但是只要是宝马品牌的汽车,它的车头一定会有宝马汽车的logo,那么这个就是大家最直观去确认一辆车是不是宝马牌…...
MyBatis Plus 中 LocalDateTime 引发的一些问题和解决办法
简介 在使用 MyBatis Plus 进行数据库操作时,我们经常会遇到处理日期时间类型的需求。然而,在某些情况下,使用 LocalDateTime 类型可能会引发一些问题。本文将详细介绍这些问题,并提供相应的解决办法。 问题描述: 1…...
谁懂啊!自制的科普安全手册居然火了
自制的科普安全手册居然火了 谁懂啊! 嗨嗨嗨!小仙女们,有没有见过这样的可以翻页的电子安全手册呢?自己随手就能轻松制作手册,结果一晚浏览量这么多!这可真是让人又惊又喜啊!快来分享一下我的喜…...
强化学习-论文调研-泛化性能力度量
1.[ICML2019]Quantifying Generalization in Reinforcement Learning 文章提出16000多个单智能体闯关游戏CoinRun,通过智能体在分割开的训练环境和测试环境上表现的性能作为RL泛化性的度量。具体而言作者通过”奔跑硬币泛化曲线“ (CoinRun Gener…...
CSS中图片旋转超出父元素解决办法
下面的两种解决办法都会导致图片缩小,可以给图片进行初始化的宽高设置 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge">…...
QML、C++ 和 JS 三者之间的交互
QML、C++ 和 JS 三者之间的交互是 Qt Quick 应用开发的核心。以下是它们之间交互的常见方式: 从 QML 调用 C++ 函数要从 QML 调用 C++ 函数,您可以使用 Qt 的 QML 注册机制,例如 qmlRegisterType,将 C++ 类注册为 QML 类型。 C++ 代码: #include <QGuiApplication>…...
ProEasy机器人:TCP无协议通讯(socket通讯)时打印log日志
打印日志需要调用lua中的io相关文件函数与os相关时间函数,代码如下 --------TCP无协议视觉通讯------- function open_client_Vision() --连接视觉服务器 打开以太网作为客户端 repeat FreePort.ECM_CloseAll() --关闭所有链接 …...
算法通过村第六关-树白银笔记|层次遍历
文章目录 前言1. 层次遍历介绍2. 基本的层次遍历与变换2.1 二叉树的层次遍历2.2 层次遍历-自底向上2.3 二叉树的锯齿形层次遍历2.4 N叉树的层次遍历 3. 几个处理每层元素的题目3.1 在每棵树行中找出最大值3.2 在每棵树行中找出平均值3.3 二叉树的右视图3.4 最底层最左边 总结 前…...
SpringCloud理解篇
一、微服务概述 1、什么是微服务 目前的微服务并没有一个统一的标准,一般是以业务来划分将传统的一站式应用,拆分成一个个的服务,彻底去耦合,一个微服务就是单功能业务,只做一件事。 与微服务相对的叫巨石 。 2、微服…...
编写LED灯的驱动,实现三盏灯的控制
mychrdev.c #include <linux/init.h> #include <linux/module.h> #include <linux/fs.h> #include <linux/uaccess.h> #include <linux/io.h> #include "head.h"unsigned int major; // 保存主设备号 char kbuf[128]{0}; unsigned int…...
Flink报错处理-1
在 flink job 运行一段时间后,观察日志发现出现了如下的 warn日志: The operator name {} exceeded the {} characters length limit and was truncated 完整的 warn 日志如下: The operator name TriggerWindow(GlobalWindows(), ListStat…...
bim与数字孪生智能建造的关系
随着建筑业数字化改革的推进,我们正迈入数字孪生时代,而真正实现建筑物数字孪生的智能建造,其基础前提是建造对象和建造过程的高度数字化,这样一个过程唯有依托BIM建立数据模型才能实现,真正达到智能建造或智慧运维。 …...
【Linux】进程篇(补):守护进程
文章目录 1. 补充1.1 查看1.2 控制进程组的方式 2. 创建守护进程step1. 忽略信号step2. 让自己不是组长step3. setsid 函数:给调用函数设置新的会话和进程组 IDstep4. chdir 函数:可以改变守护进程的工作路径step5. 处理文件描述符 0、1、2 守护进程类样…...
SpringMVC自定义视图完成步骤 和 视图解析的源码剖析
自定义视图完成步骤: ● 7.2.1自定义视图完成步骤 1. 自定义视图**:** 创建一个 View 的 bean, 该 bean 需要继承自 AbstractView, 并实现 renderMergedOutputModel 方法**.** 2. 并把自定义 View 加入到 IOC 容器中 3. 自定义视图的视图处理器,使用…...
合宙Air724UG LuatOS-Air lvgl字库
目录 LVGL 简介1. lvgl自带字库 特点使用场景2. lvgl加载外部字体 软件接口使用场景3. lvgl 矢量字体 软件接口硬件外接SPI字库芯片详细使用示例使用场景常见问题 LVGL 简介 LVGL字库有3种方式可以使用,刚接触的客户可能不太了解怎样选用,以下对这3种…...
C#,数值计算——指数微分(exponential deviates)的计算方法与源程序
1 文本格式 using System; namespace Legalsoft.Truffer { /// <summary> /// 指数偏差 /// Structure for exponential deviates. /// </summary> public class Expondev : Ran { private double beta { get; set; } /// <s…...
ADAS自动驾驶
文章目录 ADAS技术现状ADAS功能的主流方案ADAS控制器开发自动驾驶技术现状自动驾驶域控制器开发智能驾驶域控制器芯片选择 ADAS技术现状 自动驾驶辅助系统(ADAS,Advanced Driver Assistance Systems)是一种用于提高驾驶安全和舒适性的技术&a…...
Python从零到一构建项目
随着互联网的发展,网络上的信息量急剧增长,而获取、整理和分析这些信息对于很多人来说是一项艰巨的任务。而Python作为一种功能强大的编程语言,它的爬虫能力使得我们能够自动化地从网页中获取数据,大大提高了效率。本文将分享如何…...
使用todesk或者向日葵远程Ubuntu22.04系统的客户机黑屏
[TOC](使用todesk或者向日葵远程Ubuntu22.04系统的客户机黑屏) 目录 1. 故障现象 2. 分析 3. 解决办法 4. 参考文章 1. 故障现象 使用todesk或者向日葵远程客户机(Ubuntu22.04系统)时,显示黑屏 2. 分析 本故障可能是因为Ubuntu22.04的图…...
JBoss JMXInvokerServlet 反序列化漏洞复现(CVE-2015-7501)
一、漏洞说明 JBoss中/invoker/JMXInvokerServlet路径对外开放,JBoss的jmx组件支持反序列化。JBoss在/invoker/JMXInvokerServlet请求中读取了用户传入的对象,然后我们利用Apache Commons Collections中的Gadget执行任意代码。 二、影响版本 JBoss Enter…...
铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
多模态2025:技术路线“神仙打架”,视频生成冲上云霄
文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...
Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...
【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...
线程与协程
1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...
Web中间件--tomcat学习
Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机,它可以执行Java字节码。Java虚拟机是Java平台的一部分,Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...
前端开发者常用网站
Can I use网站:一个查询网页技术兼容性的网站 一个查询网页技术兼容性的网站Can I use:Can I use... Support tables for HTML5, CSS3, etc (查询浏览器对HTML5的支持情况) 权威网站:MDN JavaScript权威网站:JavaScript | MDN...
向量几何的二元性:叉乘模长与内积投影的深层联系
在数学与物理的空间世界中,向量运算构成了理解几何结构的基石。叉乘(外积)与点积(内积)作为向量代数的两大支柱,表面上呈现出截然不同的几何意义与代数形式,却在深层次上揭示了向量间相互作用的…...
