Liskov替代例外原则

时间:2019-03-17 10:59:01

标签: inheritance polymorphism liskov-substitution-principle

我正在“敏捷原则,模式和实践”一书中阅读有关LSP的内容。 它指出:

  

“ [衍生形式]的例行重新声明可能   只能用一个等于或小于一个的原先决条件,然后用一个等于或大于一个的原先条件。”

     

弱者一词可能会造成混淆。如果X不执行Y的所有约束,则X比Y弱。   X施加了许多新的约束。

在异常情况下我们如何理解它?

1 个答案:

答案 0 :(得分:1)

LSP适用于类型。因此,大多数OOP语言中的类。然后可以通过三种方式考虑您的问题:

1。视为类型的例外

异常类型,例如C ++中的std::exception,可以派生为更特殊的异常。为了便于错误处理,应使用LSP。

异常通常在行为上很差,并且仅传输有关错误条件的一些其他信息,因此一般来说并不太困难。

2。异常被视为失败的前提条件

异常应对应于正常情况下不会出现的异常情况。因此,引发异常意味着没有预期的正常条件。

因此,在派生类型中引发异常的条件应等于或弱于常规类型。

让我们来看看极端情况。假设在给定的例程的基类中没有预见到异常。您可能期望甚至指定一个nothrow。使用此例程的代码将认为它是安全的,并且不会预见任何异常捕获。假设您然后将该类派生到引发异常的类中(即前提条件更强,更严格):如果引发异常,则为基类编写的代码将措手不及,并且可以为基类提供通用代码被专业班打破。因此,LSP将被破坏。

3。例外被视为特殊结果/后置条件

您可能会争辩说,在某些情况下,例外是特殊的后置条件。返回值的替代方法。

对于这种解释,我会感到不舒服(因为这不是许多语言设计师的理解,请参阅有关零位的讨论)。但是我没有进一步的客观论据来使它无效。

由于LSP与合同有关,因此可以做出此设计决策。在这种情况下,更专业的类可以引发更专业的异常(因此推理将基于异常类型)。但是,派生类是否真的应该引发比原始类至少更多的异常?听起来有悖常理。转到2。