《后端技术面试 38 讲》学习笔记 Day 03
13丨软件设计的里氏替换原则:正方形可以继承长方形吗?
原文摘抄
里氏替换原则:关于如何设计类的继承关系,怎样使继承不违反开闭原则,实际上有一个关于继承的设计原则,叫里氏替换原则。
这个原则说:若对每个类型 T1 的对象 o1,都存在一个类型 T2 的对象 o2,使得在所有针对 T2 编写的程序 P 中,用 o1 替换 o2 后,程序 P 的行为功能不变,则 T1 是 T2 的子类型。
通俗地说就是:子类型必须能够替换掉它们的基类型。但是在实际中,如果你不严谨地审视自己的设计,是很可能违背里氏替换原则的。
继承是否合理我们需要用里氏替换原则来判断。之前也说过,是否合理并不是从继承的设计本身看,而是从应用场景的角度看。
子类不能比父类更严格。当子类继承父类的时候,根据里氏替换原则,使用者可以在使用父类的地方使用子类替换,那么从契约的角度,子类的契约就不能比父类更严格,否则使用者在用子类替换父类的时候,就会因为更严格的契约而失败。
如果你确实需要使用一个类的方法,最好的办法是组合这个类而不是继承这个类,这就是人们通常说的组合优于继承。
心得体会
- 里氏替换原则,是对继承的使用提出了规范,要求子类可以替父类的所有具体实现。
- 而我们开发中,往往子类的限定会更精确,更严格。例如有些JDBC的实现是拒绝进行使用DML语句的,理论上是违反了里氏替换原则,但是对用户无感知的完成了权限的收口。
- 组合优于继承,它的耦合度相对继承更低,更灵活。
工作体验
- 工作中,未曾从里氏替换原则出发去考虑过继承的使用是否合理,似乎也没有出过什么问题。
14 | 软件设计的单一职责原则:为什么说一个类文件打开最好不要超过一屏?
原文摘抄
软件设计有两个基本准则:低耦合和高内聚。
设计类的时候,我们应该把强相关的元素放在一个类里,而弱相关性的元素放在类的外边。保持类的高内聚性。具体设计时应该遵循这样一个设计原则:一个类,应该只有一个引起它变化的原因。
事实上,Web 应用技术的发展、演化过程,也是一个不断进行职责分离,实现单一职责原则的过程。
心得体会
- 原则不是教条,单一指责是希望做到高内聚。实际上,本身看起来已经很内聚的代码,可能在遇到新的需求后,也开始变得不够内聚。
- 评论区看到的也很有意思,一个类抽出来之后,被很多的类引用,后续的修改也是会很有包袱感的,这之间也是需要一个权衡。
工作体验
- 工作中,也有类似的处理SQL树节点的经历,也是逐渐细化,使得一个类支持一种语法,一个类支持一种函数。
但是这个就够内聚了吗,后续接入多数据源之后,类还可以继续细化!类是否单一,内聚程度是否够高,也是面向需求来做判断的。