Программирование по контракту — различия между версиями
(→Пример) |
(→Пример) |
||
Строка 55: | Строка 55: | ||
Постусловия и предусловия: | Постусловия и предусловия: | ||
+ | |||
<tex>int</tex> <tex> getHours() </tex> | <tex>int</tex> <tex> getHours() </tex> | ||
<tex>post:</tex> возвращенное значение будет являться текущим часом. | <tex>post:</tex> возвращенное значение будет являться текущим часом. | ||
+ | |||
<tex>int</tex> <tex> getMinutes() </tex> | <tex>int</tex> <tex> getMinutes() </tex> | ||
<tex>post:</tex> возвращенное значение будет являться текущей минутой. | <tex>post:</tex> возвращенное значение будет являться текущей минутой. | ||
+ | |||
<tex>int</tex> <tex> getSeconds() </tex> | <tex>int</tex> <tex> getSeconds() </tex> | ||
<tex>post:</tex> возвращенное значение будет являться текущей секундой. | <tex>post:</tex> возвращенное значение будет являться текущей секундой. | ||
+ | |||
<tex> void </tex> setHours(int newHours) | <tex> void </tex> setHours(int newHours) | ||
Строка 73: | Строка 77: | ||
<tex> post: </tex> hours == newHours | <tex> post: </tex> hours == newHours | ||
+ | |||
<tex> void </tex> setMinutes(int newMinutes) | <tex> void </tex> setMinutes(int newMinutes) | ||
Строка 79: | Строка 84: | ||
<tex> post: </tex> minutes == newMinutes | <tex> post: </tex> minutes == newMinutes | ||
+ | |||
<tex> void </tex> setSeconds(int newSeconds) | <tex> void </tex> setSeconds(int newSeconds) |
Версия 18:42, 30 сентября 2013
Программирование по контракту обеспечивает проверку предусловий и постусловий при выполнении методов классов, пользовательских функций. Также немаловажную роль в правильности написания функций играют инварианты.
Предусловие
Определение: |
Предусловие - должно быть выполнено до исполнения действия. |
Постусловие
Определение: |
Постусловие - должно быть выполнено после исполнения действия. |
Инвариант
Определение: |
Инвариант - определяет глобальные свойства некоторого класса, которые должны соблюдаться после его создания на протяжении всего времени жизни. |
Пример
Необходимо гарантировать, что функции данного класса будут возвращать корректные данные, либо, вообще не будут работать.
class Time { int hours; int minutes; int seconds; int getHours(); { return hours; } int getMinutes(); { return minutes; } int getSeconds() { return seconds; } void setHours(int newHOURS); { hours = newHOURS; } void setMinutes(int newMINUTES); { minutes = newMINUTES; } void setSeconds(int newSECONDS) { seconds = newSECONDS; } }
Инвариант:
Постусловия и предусловия:
возвращенное значение будет являться текущим часом.
возвращенное значение будет являться текущей минутой.
возвращенное значение будет являться текущей секундой.
setHours(int newHours)
0 <= newHours <= 23
hours == newHours
setMinutes(int newMinutes)
0 <= newMinutes < 60
minutes == newMinutes
setSeconds(int newSeconds)
0 <= newSeconds < 60
seconds == newSeconds
Постусловие: (например для getHours()) возвращенное значение будет являться текущим часом.
Решение 1
Выбрасывать исключение. Имеет недостатки: неочевидность проверки, необходимость писать кучу кода вручную.
void getHours(newHours){ if (newHours < 0 || newHours > 23) throw GREAT_Time_Exception; return hours; }
Решение 2
Java поддерживает механизм аннотаций (рекомендаций компилятору, препроцессору) – метаданные, которые могут быть добавлены в исходный код программы, не влияя на него семантически, т.е. не меняя его поведение. При этом, они могут использоваться на этапе анализа кода, компиляции и выполнения.
@Contracted // говорит о том, что класс использует контракты – для отображения в IDE class Time { @Ensures ({“result >= 0”,“result <= 23” }) int getHours(); { return HOURS; } @Requires ({“newHOURS>= 0”,“newHOURS<= 23” }) @Ensures (“HOURS == newHOURS”) }
@Requires – буквально означает, «Убедиться, что ДО выполнения подпрограммы («условие выполняется»)» Иначе – бросить исключение.
@Ensures – буквально означает, «Убедиться, что ПОСЛЕ выполнения подпрограммы ( «условие выполняется»)»
Здесь мы видим, что, как и в Решение 1, осуществляется проверка пред и пост условий для наших методов. В чем разница? Разница в том, что во втором случае это более наглядно и удобно.
Пример
Рассмотрим стек на массиве. У него есть переменные
число элементов
массив элементов
Методы:
добавить элемент
удалить элемент
получить элемент на вершине
число элементов
проверка на пустоту
Инвариант:
Размер не отрицателен,
Элементы заполнены
Контракты: