Определение и пример

Определение и пример

Рассмотрим снова реализацию стека классом STACK2:

class STACK2 [G] creation

make

feature

? make, empty, full, item, put, remove?

capacity: INTEGER

count: INTEGER

feature {NONE} -- Implementation

representation: ARRAY [G]

end

Атрибуты класса - массив representation и целые capacity, count - задают представление стека. Хотя предусловия и постусловия программ отражают семантику стека, их недостаточно для выражения важных свойств, связывающих атрибуты. Например, count всегда должно удовлетворять условию:

0 <= count; count <= capacity

из которого следует, что capacity >=0 и что capacity задает размер массива:

capacity = representation.capacity

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

Выше приведенные примеры инвариантов включали только атрибуты. Инварианты могут выражать отношения между функциями и между функциями и атрибутами. Например, инвариант STACK2 может включать следующее свойство, описывающее связь между функцией empty и count:

empty = (count = 0)

Этот пример не показателен, он повторяет утверждение, заданное постусловием empty. Более полезные утверждения те, которые включают только атрибуты или более чем одну функцию.

Вот еще один типичный пример. Предположим, что мы имеем дело с банковскими счетами, и есть класс Bank_Account с компонентами: deposits_list, withdrawals_list и balance. Тогда инвариантом такого класса может быть утверждение в форме:

consistent_balance: deposits_list.total - withdrawals_list.total = balance

где функция total дает суммарное значение списка всех операций (приходных или расходных). Инвариант определяет основное условие согласования всех банковских операций над счетом, связывая баланс, приходные и расходные операции.