软件开发培训:里氏替换原则丨鸵鸟的例子

  文章来源:http://www.zretc.com/technologyDetail/478.html

  "里氏替换原则"听起来非常的复杂,但是设计思想却是非常基础的。看下面这个有趣的海报——

  里氏替换原则海报

  这一原则描述了:

  "子类型必须能够替换它们的基类。"

  或者, 换句话说:

  "使用基类引用的函数必须能够使用派生类而无须了解派生类。"

  同学:对不起, 这听起来让我觉得有点乱。我认为这个是面向对象编程的基本原则。这个叫做多态性, 对吧? 为什么面向对象设计原则需要考虑这个问题?

  小卓:非常好的问题!这有一些答案:

  在基本的面向对象原则中,"继承" 通常被描述成 "is a" 的关系。如果一个 "开发者" 是"软件专业人员"那么 "开发者" 类 应该继承 "软件开发人员" 类。这样的 "Is a" 关系在类设计阶段非常重要,但是这也很容易让设计者得意忘形从而以一个糟糕的继承设计告终。

  "里氏替换原则" 仅仅是一种确保继承被正确使用的手段。

  同学:我明白了,真有趣!

  小卓:是的,确实如此。让我们来看看一个例子:

  类层次结构图展示的是一个Liskov替换原则的例子。因为 KingFisher(翠鸟)类拓展(继承)了Bird类,因此继承了Fly()这个方法,这是非常不错的。

  我们再来看看下面的例子:

  修正过的Liskov替换原则的类层次结构图

  Ostrich(鸵鸟)是一种鸟(显然是),并继承了 Bird 类。但它能飞吗?不能,这个设计就违反了里氏替换原则。

  因此,即使在现实中看上去没什么问题,在类设计中,Ostrich 都不应该继承 Bird 类,而应该从 Bird 中分出一个不会飞的类,由 Ostrich 继承。

  同学:好吧,明白了。我说说为什么里氏替换原则如此重要:

  · 如果不遵循 LSP原则,类继承就会混乱。如果子类实例被作为参数传递给方法,后果难以预测。

  · 如果不遵循 LSP原则,基于父类编写的单元测试代码将无法成功运行子类。

  我说的对吗?

  小卓:完全正确,你可以设计一个对象并用LSP作为验证工具来测试该对象是否能够继承。

  下一篇文章,我们将讨论“面向对象之接口隔离原则”

  出处:开源中国

  译者:K6F, 凡程子, 叫我蝴蝶吧, 王薇, 人头马没面, 铂金小龟, 风子, nikeff1108, sigai

  链接:http://www.oschina.net/translate/how-i-explained-ood-to-my-wife?lang=chs&page=4#

  了解更多软件开发常见原则问题欢迎登陆中软国际教育集团技术知识库!

时间: 2024-10-10 00:29:23

软件开发培训:里氏替换原则丨鸵鸟的例子的相关文章

敏捷软件开发 – LSP Liskov替换原则

Liskov替换原则:子类型(subtype)必须能够替换掉它们的基类型(basetype). 违反LSP的情形 对于LSP的违反常常会导致以明显违反OCP的方式使用运行时类型检查.通常,会使用一个显式的if语句或者if/else链去确定一个对象的类型,以便于可以选择针对该类型的正确行为. struct Point { double x, y;} public enum ShapeType { square, circle }; public class Shape { private Shap

软件开发培训:开闭原则丨穿衣服的例子

文章来源:http://www.zretc.com/technologyDetail/477.html 软件开发中经常需要注意的原则有哪些呢?开闭原则就是其中之一 "开闭原则"图示如下: 让我来解释一下,设计规则如下: "软件实体(类,模块,函数等)应该对扩展开放,对修改关闭." 这意味着在最基本的层面上,你可以扩展一个类的行为,而无需修改.这就像我能够穿上衣服,而对我的身体不做任何改变,哈哈. 同学:太有意思啦. 你可以通过穿不同的衣服来改变你的外貌, 但是你不必

深入理解JavaScript系列(8):S.O.L.I.D五大原则之里氏替换原则LSP

前言 本章我们要讲解的是S.O.L.I.D五大原则JavaScript语言实现的第3篇,里氏替换原则LSP(The Liskov Substitution Principle ). 英文原文:http://freshbrewedcode.com/derekgreer/2011/12/31/solid-javascript-the-liskov-substitution-principle/ 开闭原则的描述是: Subtypes must be substitutable for their ba

依赖注入的本质与里氏替换原则

根据开闭原则或(依赖倒置原则)控制翻转原则建立了稳定的抽象层. 抽象层中的抽象组件(元素)不能实例化,需要在运行时用子类对象进行替代. 这个抽象组件被替代的过程就是依赖注入. 依赖注入解决的是如何用子类替代父类的问题. 里氏替换原则,OCP作为OO的高层原则,主张使用“抽象(Abstraction)”和“多态(Polymorphism)”将设计中的静态结构改为动态结构,维持设计的封闭性.“抽象”是语言提供的功能.“多态”由继承语义实现. 里氏替换原则中说,任何基类可以出现的地方,子类一定可以出现

里氏替换原则(Liskov Substitution Principle)

开放封闭原则(Open Closed Principle)是构建可维护性和可重用性代码的基础.它强调设计良好的代码可以不通过修改而扩展,新的功能通过添加新的代码来实现,而不需要更改已有的可工作的代码.抽象(Abstraction)和多态(Polymorphism)是实现这一原则的主要机制,而继承(Inheritance)则是实现抽象和多态的主要方法. 那么是什么设计规则在保证对继承的使用呢?优秀的继承层级设计都有哪些特征呢?是什么在诱使我们构建了不符合开放封闭原则的层级结构呢?这些就是本篇文章将

设计模式六大原则(2):里氏替换原则

里氏替换原则 肯定有不少人跟我刚看到这项原则的时候一样,对这个原则的名字充满疑惑.其实原因就是这项原则最早是在1988年,由麻省理工学院的一位姓里的女士(Barbara Liskov)提出来的. 定义1:如果对每一个类型为 T1的对象 o1,都有类型为 T2 的对象o2,使得以 T1定义的所有程序 P 在所有的对象 o1 都代换成 o2 时,程序 P 的行为没有发生变化,那么类型 T2 是类型 T1 的子类型. 定义2:所有引用基类的地方必须能透明地使用其子类的对象. 问题由来:有一功能P1,由

里氏替换原则

传统的继承有其缺陷? 良好的继承应该是在实现继承时,子类必须能够替换掉他们的基类,如果一个软件代码中使用的是基类的话,那么也一定可以使用其子类. 里氏替换原则的好处 保证了父类的复用性,同时也能够降低系统出错误的故障,防止误操作,同时也不会破坏继承的机制,这样继承才显得更有意义. 指导原则. (1)子类可以实现父类的抽象方法,但是不能覆盖父类的非抽象方法. (2)子类中可以增加自己特有的方法. (3)当子类重载父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松.(个人感觉如

里氏替换原则(Liskov Substitution Principle, LSP)

以此回顾所读<设计模式之禅>与<高校程序员的45个习惯>中Liskov部分 定义: 第一种:If for each object O1 of type S there is an object O2 fo type T such that for all programs P defined in terms of T, the behavior of P is unchanged when O1 is substitueted for O2 then S is a subtype

Java 设计模式(十一) 里氏替换原则(LSP)

里氏替换原则(Liskov Substitution Principle) LSP的基本概念 定义: 所有引用基类的地方必须能透明地使用其子类的对象 只要父类能出现的地方子类就可出现,而且替换为子类也不会产生任何错误或异常,使用者可能根本就不需要知道是父类还是子类(封装造成的多态性) 规范 子类必须完全实现父类的方法 在类中调用其他类时必然要使用父类或者接口,如果子类中不支持父类中的方法,自然就违背了LSP 子类要有自己的特性 子类是在父类的基础上实现的,有自己的特性 这也就导致了LSP的单向性