Изменения

Перейти к: навигация, поиск

Программирование по контракту

1127 байт добавлено, 21:29, 30 сентября 2013
Пример
== Пример ==
Необходимо гарантировать, что функции данного класса будут возвращать корректные данные, либо, вообще не будут работать.
public class Time { private int hours; private int minutes; private int seconds; public int getHours();
{
return hours;
}
public int getMinutes();
{
return minutes;
}
public int getSeconds()
{
return seconds;
}
public void setHours(int newHOURS);
{
hours = newHOURS;
}
public void setMinutes(int newMINUTES);
{
minutes = newMINUTES;
}
public void setSeconds(int newSECONDS)
{
seconds = newSECONDS;
}
}
ПредусловиеИнвариант:   hours >= 0 and hours <= 23   minutes >= 0 and minutes < 60  seconds >= 0 and seconds < 60  Постусловия и предусловия:   int getHours() post: возвращенное значение будет являться текущим часом.   int getMinutes(например для getHours) post: возвращенное значение будет являться текущей минутой.   int getSeconds() post: возвращенное значение будет являться текущей секундой.   void setHours(int newHours) pre: 0 <= newHours <= 23 post: hours >= = newHours   void setMinutes(int newMinutes) pre: 0 <= newMinutes < 60 post: minutes == newMinutes    void setSeconds(int newSeconds) pre: 0 && hours <= 23.newSeconds < 60 post: seconds == newSeconds
Постусловие: возвращенное значение будет являться текущим часом.
==== Решение 1 ====
Выбрасывать исключение. Имеет недостатки: неочевидность проверки, необходимость писать кучу кода вручную.
void setHours(int getHours(newHours){ if (this.hours newHours < 0 || this.hours newHours > 23)
throw GREAT_Time_Exception;
return hours= newHours;
}
@Contracted // говорит о том, что класс использует контракты – для отображения в IDE
class Time
{ @Ensures void setHours({“result >= 0”,“result <= 23” }) int getHours(newHours);
{
return HOURShours = newHours;
}
@Requires ({“newHOURS>= 0”,“newHOURS<= 23” })
@Ensures (“HOURS “hours == newHOURS”)
}
@Requires – буквально означает, «Убедиться, что ДО выполнения подпрограммы («условие выполняется»)» Иначе – бросить исключение.
<tex> isEmpty - </tex> проверка на пустоту
 
public class ArrayStack {
private int size = 0;
private Object[] elements = new Object[2];
public void push(Object element){
assert element != null;
ensureCapacity(size + 1);
elements[size++] = element;
}
private void ensureCapacity(int capacity) {
if (capacity <= elements.length) {
return;
}
Object[] newElements = new Object[2 * capacity];
for (int i = 0; i < size; i++) {
newElements[i] = elements[i];
}
elements = newElements;
}
public Object pop() {
assert size > 0;
return elements[--size];
}
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
public Object peek() {
assert size > 0;
return elements[size - 1];
}
}
Инвариант:
Контракты:
<tex> push </tex> <tex> pre: element != NULL </tex> <tex> post: size = size' + 1</tex> <tex> and </tex> <tex> elements[size'] == element </tex> <tex> void</tex> push (Object</tex> <tex> element) </tex>  <tex> pop:</tex> <tex> pre: size > 0 </tex> <tex>post: size == size' - 1</tex> <tex> and </tex> <tex>result == elements[size]</tex> <tex> Object</tex> <tex> pop() </tex>   <tex> peek:</tex> <tex>pre: size > 0</tex> <tex>post: result == elements[size - 1]</tex><tex> Object</tex> <tex> peek() </tex>  <tex> size:</tex> <tex>post: result == size </tex> <tex>int</tex> <tex> size()</tex>
pop
pre: size > 0
post: size == size' - 1 and result == elements[size]
Object pop()
<tex peek pre: size >isEmpty0 post:</tex>result == elements[size - 1] Object peek()
<tex> size post: result == size > 0</tex> int size()
<tex isEmpty post: result == size >0 boolean</tex> <tex>isEmpty() </tex>
Анонимный участник

Навигация