敏捷开发笔记(第10章节)--Liskov原则(LSP)
目录
1:PDF上传链接
10.1 Liskov替换原则(LSP)
10.2 一个违反LSP的简单例子
10.6 启发式规则和习惯用法
10.7 结论
1:PDF上传链接
【免费】敏捷软件开发(原则模式与实践)资源-CSDN文库

OCP背后的主要机制是抽象(abstraction)和多态(polymorphism)。在静态类型语言中,比如C++和Java,支持抽象和多态的关键机制之一是继承(inheritance)。正是使用了继承,我们才可以创建实现其基类(base class)中抽象方法的派生类。
是什么设计规则在支配着这种特殊的继承用法呢?最佳的继承层次的特征又是什么呢?怎样的情况会使我们创建的类层次结构掉进不符合OCP的陷阱中去呢?这些正是Liskov替换原则(LSP)要解答的问题。
10.1 Liskov替换原则(LSP)
对于LSP可以做如下解释:
子类型(subtype)必须能够替换掉它们的基类型(base type).
Barbara Liskov首次写下这个原则是在1988年。她说道,
这里需要如下替换性质:若对每个类型S的对象01,都存在一个类型T的对象02,使得在所有针对T编写的程序P中,用01替换02后,程序P行为功能不变,则S是T的子类型.
想想违反该原则的后果,LSP的重要性就不言而喻了。假设有一个函数f,它的参数为指向某个基类B的指针(pointer)或者引用(reference.)。同样假设有B的某个派生类D,如果把D的对象作为B类型传递给f,会导致f出现错误的行为。那么D就违反了LSP。显然,D对于f来说是脆弱的。
f的编写者会想去对D进行一些测试,以便于在把D的对象传递给f时,可以使f具有正确的行为。这个测试违反了OCP,因为此时f对于B的所有不同的派生类都不再是封闭的。这样的测试是一种代码的臭味,它是缺乏经验的开发人员(或者,更糟的,匆忙的开发人员)在违反了LSP时所产生的结果。
10.2 一个违反LSP的简单例子
对于LSP的违反常常会导致以明显违反OCP的方式使用运行时类型辨别(RTTI)。这种方式常常是使用-“个显式的仟语句或者fse链去确定一个对象的类型,以便于可以选择针对该类型的正确行为。考虑…下程序10.1。

图10.1.1
很显然,程序lO.1中的DrawShape函数违反了OCP。它必须知道Shape类所有的派生类,并且每次创建-一个从Sape类派生的新类时都必须要更改它,甚至很多人肯定地认为这种函数结构简直是对良好设计的诅咒。那么,是什么促使程序员编写出像这样的一个函数呢?
假设Jo是一个工程师。他学习过面向对象技术,并且认为多态的开销大得难以忍受。因此,他定义了一个没有任何虚函数的Shape类。类(结构)Square和Circle从Shape类派生,并具有Draw)函数,但是它们没有覆写(override)Shape类中的函数。因为Circle类和Square类不能替换Shape类,所以DrawShape函数必须要仔细检查输入的Shape对象,确定它的类型,接着调用正确的Draw函数。
Square类和Circle类不能替换Shape类其实是违反了LSP,这个违反又迫使DrawShape函数违反了OCP,因而,对于LSP的违反也潜在地违反了OCP。
10.6 启发式规则和习惯用法
有一些简单的启发规则可以提供一些有关违反LSP的提示。这些规则都和以某种方式从其基类中去除功能的派生类有关。完成的功能少于其基类的派生类通常是不能替换其基类的,因此就违反了LSP。
10.7 结论
OCP是OOD中很多说法的核心。如果这个原则应用得有效,应用程序就会具有更多的可维护性、可重用性以及健壮性。LSP是使OCP成为可能的主要原则之一。正是子类型的可替换性才使得使用基类类型的模块在无需修改的情况下就可以扩展。这种可替换性必须是开发人员可以隐式依赖的东西。因此,如果没有显式地强制基类类型的契约,那么代码就必须良好地并且明显地表达出这一点。
术语“IS-A”的含意过于宽泛以至于不能作为子类型的定义。子类型的正确定义是“可替换性的”,这里的可替换性可以通过显式或者隐式的契约来定义。
相关文章:
敏捷开发笔记(第10章节)--Liskov原则(LSP)
目录 1:PDF上传链接 10.1 Liskov替换原则(LSP) 10.2 一个违反LSP的简单例子 10.6 启发式规则和习惯用法 10.7 结论 1:PDF上传链接 【免费】敏捷软件开发(原则模式与实践)资源-CSDN文库 OCP背后的主要机制是抽象(abstraction…...
基于SSM的校园一卡通管理系统的设计与实现
摘 要 本报告全方位、深层次地阐述了校园一卡通管理系统从构思到落地的整个设计与实现历程。此系统凭借前沿的 SSM(Spring、Spring MVC、MyBatis)框架精心打造而成,旨在为学校构建一个兼具高效性、便利性与智能化的一卡通管理服务平台。 该系…...
新版Android Studio中设置gradle的JDK版本
旧版android studio 在旧版(具体哪个版本号之前搞不清了)中设置JDK版本在>File——>Project Structure——>SDK location——>Gradle Setting——>Gradle SDK 新版android studio 某次更新后发现SDK location下找不到Gradle Setting选项…...
打造你的智能家居指挥中心:基于STM32的多协议(zigbee、http)网关(附代码示例)
1. 项目概述 随着物联网技术的蓬勃发展,智能家居正逐步融入人们的日常生活。然而,市面上琳琅满目的智能家居设备通常采用不同的通信协议,导致不同品牌设备之间难以实现互联互通。为了解决这一难题,本文设计了一种基于STM32的多协…...
【基于R语言群体遗传学】-16-中性检验Tajima‘s D及连锁不平衡 linkage disequilibrium (LD)
Tajimas D Test 已经开发了几种中性检验,用于识别模型假设的潜在偏差。在这里,我们将说明一种有影响力的中性检验,即Tajimas D(Tajima 1989)。Tajimas D通过比较数据集中的两个𝜃 4N𝜇估计值来…...
防火墙组网与安全策略实验
实验要求: 实现: 防火墙接口配置: 所有接口均配置为三层接口 由于G1/0/3口下为vlan环境,所以防火墙需要配置子接口 : 交换机划分vlan分开生产区和办公区、配置trunk干道 : 安全策略: 生产区访…...
xmind梳理测试点,根据这些测试点去写测试用例
基本流(冒烟用例必写) 备选流 公共测试点:...
MICCAI 2024 每日一篇论文 纯纯直读 CUTS:用于多粒度无监督医学图像分割的深度学习和拓扑框架
MICCAI 2024 CUTS: A Deep Learning and Topological Framework for Multigranular Unsupervised Medical Image Segmentation CUTS: 用于多粒度无监督医学图像分割的深度学习和拓扑框架 作者 陈璐1*、Matthew Amodio1*、梁博伦.沈2、冯高3、阿曼阿维斯塔4、Sanjay Aneja3,5…...
实验9 存储过程与函数的创建管理实验
一、实验目的: 理解存储过程和函数的概念。掌握创建存储过程和函数的方法。掌握执行存储过程和函数的方法。掌握游标的定义、使用方法。 二、实验内容 1.某超市的食品管理的数据库的Food表,Food表的定义如表所示, Food表的定义…...
计算机网络--tcpdump和iptable设置、内核参数优化策略
tcpdump工具 tcpdump命令: 选项字段: 过滤表达式: 实用命令: TCP三次握手抓包命令: #客户端执行tcpdump 抓取数据包 tcpdump -i etho tcp and host 192.168.12.36 and port 80 -W timeout.pcapnetstat命令 netst…...
Vue3框架搭建2:axios+typescript封装
仓库地址:https://github.com/buguniao5213/LuArch 1、安装axios npm install axios2、创建文件 先创建一个文件夹: ├── src/ │ ├── api/ │ │ ├── index.ts/ #编写axios封装代码 │ │ └── example.ts/ #定义…...
【机器学习】使用决策树分类器预测汽车安全性的研究与分析
文章目录 一、决策树算法简介决策树的结构分类和回归树 (CART)决策树算法术语决策树算法直觉 二、属性选择度量信息增益熵 基尼指数计算分割基尼指数的步骤 三、决策树算法中的过度拟合避免过度拟合的方法 四、导入库和数据可视化探索性数据分析重命名列名查看数据集的总结信息…...
【香橙派 Orange pi AIpro】| 开发板深入使用体验
目录 一. 🦁 写在前面二. 🦁 愉快的安装流程2.1 安装前准备2.2 流程准备2.2.1 烧录镜像2.2.2 开机2.2.3 连网2.2.4 SSH远程连接开发板 2.3 体验 AI 应用样例 三. 🦁 写在最后 一. 🦁 写在前面 大家好,我是狮子呀&…...
初识Laravel(Laravel的项目搭建)
初识Laravel(Laravel的项目搭建) 一、项目简单搭建(laravel)1.首先我们确保使用国内的 Composer 加速镜像([加速原理](https://learnku.com/php/wikis/30594)):2.新建一个名为 Laravel 的项目&a…...
RequestContextHolder多线程获取不到request对象
RequestContextHolder多线程获取不到request对象,调用feign接口时,在Feign中的RequestInterceptor也获取不到HttpServletRequest问题解决方案。 1.RequestContextHolder多线程获取不到request对象 异常信息,报错如下: 2024-07-0…...
打造高效工作与生活质量的完美平衡
在快节奏的编程行业中,保持健康的工作与生活平衡是至关重要的。长时间坐在电脑前、面对紧凑的项目截止日期和频繁的加班文化,很容易导致身心健康问题,如眼睛疲劳、颈部和背部疼痛、压力累积、睡眠障碍乃至慢性疾病。因此,采取积极…...
【零基础】学JS之APIS第四天
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 非常期待和您一起在这个小…...
走进linux
1、为什么要使用linux 稳定性和可靠性: Linux内核以其稳定性而闻名,能够持续运行数月甚至数年而不需要重新启动。这对于服务器来说至关重要,因为它们需要保持长时间的稳定运行,以提供持续的服务 安全性: Linux系统…...
智能家居开发新进展:乐鑫 ESP-ZeroCode 与亚马逊 ACK for Matter 实现集成
日前,乐鑫 ESP-ZeroCode 与亚马逊 Alexa Connect Kit (ACK) for Matter 实现了集成。这对智能家居设备制造商来说是一项重大进展。开发人员无需编写固件或开发移动应用程序,即可轻松设计符合 Matter 标准的产品。不仅如此,开发者还可以在短短…...
本地事务和分布式事务
一、本地事务 1、事务的基本特性 数据库事务的几个基本特性:原子性、一致性、隔离性、持久性。 原子性:一系列的操作整体不可拆分,要么同时成功,要么同时失败。 一致性:数据在事务的前后,业务整体一…...
测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...
C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
【决胜公务员考试】求职OMG——见面课测验1
2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...
Linux-07 ubuntu 的 chrome 启动不了
文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了,报错如下四、启动不了,解决如下 总结 问题原因 在应用中可以看到chrome,但是打不开(说明:原来的ubuntu系统出问题了,这个是备用的硬盘&a…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
【Go语言基础【12】】指针:声明、取地址、解引用
文章目录 零、概述:指针 vs. 引用(类比其他语言)一、指针基础概念二、指针声明与初始化三、指针操作符1. &:取地址(拿到内存地址)2. *:解引用(拿到值) 四、空指针&am…...
tomcat入门
1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效,稳定,易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...
