【问题标题】:Can preconditions be expressed (for verification) as simple conditions?可以将前提条件(用于验证)表示为简单条件吗?
【发布时间】:2018-09-05 15:06:07
【问题描述】:

我了解,在按合同/Liskov 原则进行设计的上下文中,先决条件是在调用代码之前应该为真的东西,例如调用者对此负责。此外,Eiffel 语言的作者表示,大多数人确实在被调用的 cade 中添加了另一个验证检查,只是作为防御性编程的一种手段。

Some time ago I read a question with a code similar to this:

    void X(int value)
    {
       if (value > 100)
         {do something...}
    }

一些评论者认为 if 语句不是先决条件,但我认为这是不对的 - 如果合同规定 V 必须为 100,那么这是额外验证先决条件,如果一个类派生自该类型并发生变化到 v > 200,这将加强前提条件,从而违反 Liskov 原则。还是不是这样?

【问题讨论】:

    标签: contract liskov-substitution-principle


    【解决方案1】:

    如您所说,前置条件被定义为在后续代码执行之前必须始终为真的条件。

    这意味着在执行其他代码之前在函数开头检查条件的任何内容都被视为前提条件。

    示例:

    //We will do something cool here
    //With an integer input
    int doSomethingCool(final int input)
    {
        //Wait, what if input is null or less than 100?
        if(null == input || input < 100)
        {
            //Return a -1 to signify an issue
            return -1;    
        }
        //The cool bit of multiplying by 50. So cool.
        final int results = input * 50;
        //Return the results;
        return results;
    }
    

    在示例中,函数 input 在执行任何其他操作之前被检查。只要条件满足,剩下的代码就会执行。

    不好的例子:

    //We will do something cool here
    //With an integer input
    int doSomethingCool(final int input)
    {
        //Want to make sure input is not null and larger than 100
        if(null != input && input > 100)
        {
            //The cool bit of multiplying by 50. So cool.
            final int results = input * 50;
            //Return the results;
            return results;
        }
        //Return a -1 to signify an issue because the
        //preconditions were not met for some reason
        return -1;
    }
    

    在示例中,前提条件是检查input 是否不是null 并且大于100。这是一个不好的前提条件,因为它可能会引入不必要的ifs 嵌套和循环。

    前提条件应该进行检查,并且仅在检查失败时返回。前提条件下不应该做任何工作。

    根据 Liskov 替换原则,如果类型 S 是类型 T 的子类型,则类型 T 可以替换为类型 S。如果S 类型覆盖doSomethingCool 并更改前提条件,则它是违规的,因为T 类型是基本定义并定义了必须满足的预期条件。

    现在为您解答

    是的,简单的条件仍然算作先决条件。只要它们位于使用该变量的所有其他代码的前面,条件就是程序所需的条件。此外,如果函数在子类型中并且正在覆盖父类,那么它不应更改前提条件。

    但是,不要将您需要在前置条件中运行的代码括起来。那是不好的做法。如果 value 需要大于 100,请检查 value &lt; 100 并在 if 检查中设置返回值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-11-30
      • 2021-02-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多