Можно ли предусловия выразить (для проверки) как простые условия?
Я понимаю, что предварительным условием в контексте принципа 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
проверять.