Программирование по контракту — различия между версиями
Sergej (обсуждение | вклад)  (→Пример)  | 
				Sergej (обсуждение | вклад)   (→Пример)  | 
				||
| Строка 107: | Строка 107: | ||
<tex>  | <tex>  | ||
| − | post: size = size' + 1</tex>   | + | post: size = size' + 1</tex> <tex>  and </tex> <tex>  elements[size'] = element </tex>  | 
<tex> void</tex> <tex> push</tex> <tex> (Object</tex> <tex> element)</tex>  | <tex> void</tex> <tex> push</tex> <tex> (Object</tex> <tex> element)</tex>  | ||
Версия 12:35, 17 июня 2013
Программирование по контракту обеспечивает проверку предусловий и постусловий при выполнении методов классов, пользовательских функций. Также немаловажную роль в правильности написания функций играют инварианты.
Предусловие
| Определение: | 
| Предусловие - должно быть выполнено до исполнения действия. | 
Постусловие
| Определение: | 
| Постусловие - должно быть выполнено после исполнения действия. | 
Инвариант
| Определение: | 
| Инвариант - определяет глобальные свойства некоторого класса, которые должны соблюдаться после его создания на протяжении всего времени жизни. | 
Пример
Необходимо гарантировать, что данный класс будет возвращать корректные данные, либо, вообще не будет работать.
 class Time {
   intHOURS;
   intMINUTES;
   intSECONDS;
   getHours();
   {
       return HOURS;
   }    
   getMinutes();
   {
       return MINUTES;
   }
   getSeconds()
   {
       return SECONDS;
   }
   setHours(newHOURS);
   {
       HOURS = newHOURS;
   }
   setMinutes(newMINUTES);
   {
       MINUTES = newMINUTES;
   }
   setSeconds(newSECONDS)
   {
       SECONDS = newSECONDS;
   }
 }
Предусловие: (например для getHours) Hours >= 0 && Hours < 24. Постусловие: возвращенное значение будет являться текущим часом.
Решение 1
Выбрасывать исключение. Имеет недостатки: неочевидность проверки, необходимость писать кучу кода вручную.
 getHours(){
       if (HOURS<0 ||HOURS>23) 
           throw GREAT_Time_Exception;
       return HOURS;
 }
Решение 2
Java поддерживает механизм аннотаций (рекомендаций компилятору, препроцессору) – метаданные, которые могут быть добавлены в исходный код программы, не влияя на него семантически, т.е. не меняя его поведение. При этом, они могут использоваться на этапе анализа кода, компиляции и выполнения.
 @Contracted // говорит о том, что класс использует контракты – для отображения в IDE
 class Time
 {
   @Ensures ({“result >= 0”,“result <= 23” })
   getHours();
   {
       return HOURS;
   }
   @Requires ({“newHOURS>= 0”,“newHOURS<= 23” })
   @Ensures (“HOURS == newHOURS”)
 }
@Requires – буквально означает, «Убедиться, что ДО выполнения подпрограммы («условие выполняется»)» Иначе – бросить исключение.
@Ensures – буквально означает, «Убедиться, что ПОСЛЕ выполнения подпрограммы ( «условие выполняется»)»
Здесь мы видим, что, как и в Решение 1, осуществляется проверка пред и пост условий для наших методов. В чем разница? Разница в том, что во втором случае это более наглядно и удобно.
Пример
Рассмотрим стек на массиве. У него есть переменные
число элементов
массив элементов
Методы:
добавить элемент
удалить элемент
получить элемент на вершине
число элементов
проверка на пустоту
Инвариант:
Размер не отрицателен,
Элементы заполнены
Контракты: