Можно ли предусловия выразить (для проверки) как простые условия?

Я понимаю, что предварительным условием в контексте принципа Desing by contract/Liskov является то, что должно быть верно до вызова кода, например, за это отвечает вызывающая сторона. Кроме того, автор языка Eiffel заявил, что большинство людей помещают еще одну проверку проверки в вызываемый код, просто как средство защитного программирования.

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, это усилило бы предварительное условие и тем самым нарушило бы принцип Лискова. Или это не так?

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. Это плохая предпосылка, потому что это может привести к ненужной вложенности ifс и петли.

Предварительные условия должны выполнять проверки и возвращаться только тогда, когда проверки не пройдены. Не должно быть никакой работы в предварительном условии.

В соответствии с принципом подстановки Лискова, если тип S это подтип типа Tзатем введите T можно заменить на тип S, Если тип S Переопределение doSomethingCool и изменяет предварительное условие, то это является нарушением, потому что тип T является базовым определением и определяет предполагаемые условия, которые должны быть выполнены.

Теперь для вашего ответа

Да, простые условия все еще считаются предварительными условиями. Пока они находятся в начале всего другого кода, который использует переменную, условие соответствует тому, что необходимо программе. Кроме того, если функция относится к подтипу и переопределяет родительский класс, она не должна изменять предварительное условие.

Тем не менее, не окружайте код, который вам нужно запустить в рамках предварительного условия. Это плохая практика. Если value должно быть больше 100, проверьте value < 100 и установить возврат в if проверять.

Другие вопросы по тегам