当前位置: 首页 > news >正文

敏捷开发笔记(第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、事务的基本特性 数据库事务的几个基本特性:原子性、一致性、隔离性、持久性。  原子性:一系列的操作整体不可拆分,要么同时成功,要么同时失败。  一致性:数据在事务的前后,业务整体一…...

机器学习在宇宙中微子快味转换检测中的实践:从逻辑回归到天体物理模拟集成

1. 项目概述:当机器学习遇见宇宙深处的“幽灵粒子” 在宇宙最狂暴的舞台——核心坍缩超新星(CCSN)和双中子星并合(NSM)事件的中心,上演着一场肉眼无法观测的微观物理盛宴。这里的主角是中微子,这…...

Marlin固件稳定性优化实战指南:从基础配置到高级调校的完整解决方案

Marlin固件稳定性优化实战指南:从基础配置到高级调校的完整解决方案 【免费下载链接】Marlin Marlin is a firmware for RepRap 3D printers optimized for both 8 and 32 bit microcontrollers. Marlin supports all common platforms. Many commercial 3D printer…...

CANoe测试效率翻倍:手把手教你用XML Test Module搭建可复用的测试套件

CANoe测试效率翻倍:手把手教你用XML Test Module搭建可复用的测试套件在车载电子系统开发中,测试环节往往占据整个项目周期的40%以上时间。面对频繁的ECU软件迭代和多样化配置需求,传统逐个脚本执行测试的方式已经无法满足敏捷开发的要求。本…...

【独家披露】DeepSeek灰度发布SLI/SLO基线标准:99.95%可用性背后的4层验证漏斗

更多请点击: https://codechina.net 第一章:DeepSeek灰度发布策略全景图 DeepSeek模型服务的灰度发布并非简单的流量切分,而是一套融合可观测性、渐进式验证与多维熔断机制的工程化闭环体系。其核心目标是在保障线上推理稳定性的同时&#x…...

Monkey测试进阶:黑白名单搭配这些隐藏参数,让你的安卓稳定性测试效率翻倍

Monkey测试进阶:黑白名单搭配这些隐藏参数,让你的安卓稳定性测试效率翻倍在持续集成和自动化测试成为标配的今天,Monkey测试早已不再是简单的随机事件生成工具。当你的测试场景从单次手动执行升级到夜间批量测试或CI流水线时,如何…...

专业构建现代化英雄联盟智能助手:基于LCU API的完整实战指南

专业构建现代化英雄联盟智能助手:基于LCU API的完整实战指南 【免费下载链接】Seraphine 英雄联盟战绩查询工具 项目地址: https://gitcode.com/gh_mirrors/se/Seraphine Seraphine是一款基于英雄联盟官方LCU API开发的开源智能助手,专为英雄联盟…...

从 ODesign 到分子世界模型:AI 制药真正要学的,不是分子,而是相互作用

AI 制药这些年讲过许多故事。 一开始讲虚拟筛选,后来讲分子生成,再后来讲 AlphaFold、扩散模型、蛋白设计、抗体设计、干湿闭环。每一代故事都有自己的热闹,也有自己的贫乏。热闹在于工具越来越多,贫乏在于许多工具仍然像一排分工…...

Unity背包拖拽实战:三坐标系映射与跨Panel交互原理

1. 这不是“拖一拖就完事”的UI小功能,而是Unity UI系统能力的实战压力测试 在Unity项目里,“背包装备拖拽”这六个字,新手常以为只是给Image加个DragHandler接口、写几行OnBeginDrag/OnDrag/OnEndDrag回调——结果上线前一周,策划…...

别再死记硬背了!用UE5动画蓝图状态机做个“开关门”交互,5分钟搞懂运行流

用UE5动画蓝图状态机实现智能门交互:从理论到实战第一次接触虚幻引擎的动画系统时,那些抽象的概念总让人望而生畏。记得我刚开始学习UE4时,光是理解"状态机"这个概念就花了整整一周时间——直到我亲手实现了一个会自动开关的门。这…...

用Python从零搭建GridWorld环境:手把手教你实现值迭代与策略迭代(附完整代码)

用Python从零搭建GridWorld环境:手把手教你实现值迭代与策略迭代(附完整代码)在强化学习领域,GridWorld就像编程界的"Hello World",是理解基础算法的最佳试验场。不同于理论推导的抽象,亲手构建一…...