【发布时间】:2017-01-05 21:18:30
【问题描述】:
假设我有一个抽象类bird,它的一个功能是fly(int height)。
我有许多不同的鸟类类,每个类都有自己不同的飞行实现,并且该函数在整个应用程序中广泛使用。
有一天我的老板来要求我添加一只鸭子,它可以做其他鸟做的所有事情,只是它不会飞,而是在应用程序的池塘里游泳。
将鸭子添加为鸟的子类型违反了 Liskov 替换规则,因为在调用duck.fly 时,我们要么抛出异常,不执行任何操作,要么违反正确性原则。
您将如何在牢记 SOLID 设计原则的同时引入此更改?
【问题讨论】:
-
并非真正违反 LSD。退化的实现只是破坏 LSD 的一个迹象。您应该考虑您的 fly() 方法的合同。如果 Duck 的 fly() 什么都不做,客户端会受到什么影响?
-
这个问题和著名的三角形和正方形问题类似。我认为鸭子不应该是鸟类的子类型。
-
不违反 LSP,除非您在
duck.fly()中抛出异常,或者您违反了该方法的某些后置条件或Bird类的不变量(在这样的人为的例子) -
这是一种违规行为,提醒您 - 规则说,如果您的类 S 是 T 的子类型,那么您应该能够将 T 换成 S 并且仍然会得到类似的行为。什么都不做或抛出异常总是被定义为违反规则。如果您使用 java 附带的某些功能却发现它什么也没做,您会怎么想? :)
标签: design-patterns design-principles liskov-substitution-principle