Как определить, что такое инвариант? - PullRequest
0 голосов
/ 18 июля 2011

Проще говоря, при разработке нового класса, как мне выяснить, каким должен быть инвариант?Что определяет инвариант?Я слышал, что это связано с действительностью, но это все еще неоднозначно.То, что делает данный экземпляр действительным или недействительным, является спорным.

Должен ли я просто пойти с моим "внутренним" чувством?Существуют ли рекомендации для определения того, что такое инвариант?

1 Ответ

2 голосов
/ 18 июля 2011

Инвариант всегда можно представить в виде предиката, аргументами которого являются некоторые или все переменные состояния (поля) класса. Один класс может иметь более одного инварианта. Например, предположим, что у вас есть класс Account, который имеет initialBalance, listOfTransactions, currentBalance. Кроме того, мы храним транзакции в отсортированном (по дате) списке. для этого класса есть как минимум два инварианта, которые должны поддерживаться:

1) initialBalance + сумма (сумма транзакции) = currentBalance
2) для каждого элемента в listOfTransactions timestamp транзакций в позиции i всегда должно быть меньше timestamp транзакции в позиции j, если i < j.

Инварианты зависят от того, что делает class, а также от того, как реализован класс.

Допустим, мы можем добавить еще одну переменную состояния: closedDate, и появится еще один инвариант: ни у одной транзакции не может быть даты после closeDate.

Или, если список будет отсортирован не по дате, а по сумме транзакции, то участники изменятся.

Другой пример:
Предположим, у вас есть класс mutable Ellipse, определенный с двумя полями, r1 и r2, который имеет сеттеры для r1 и r2. Этот класс не имеет никакого инварианта, так как любые значения для r1 и r2 могут представлять хорошо определенный эллипс.

Теперь давайте предположим, что вы создаете новый класс Circle, который расширяет изменяемый Ellipse. Круг имеет только один радиус, добавьте, что инвариант будет (r1 == r2). Чтобы сохранить инвариант, вы должны запретить кому-либо устанавливать r1 или r2, так что происходит r1! = R2.

С другой стороны, если Ellipse и Circle являются неизменяемыми , вам не нужно заботиться об инвариантах в течение срока службы объектов, поскольку условие будет проверяться только во время строительства ,

В предыдущих примерах я хотел объяснить, что
1) способ установления и поддержки инвариантов во многом зависит от выбора дизайна отношений между классами.
2) Что делает класс
3) Как реализован класс.

Неизменяемые классы, как правило, менее сложны для поддержания своего инварианта, так как они создаются при построении и никогда не изменяются. (Неизменность имеет и много других преимуществ - не в рамках ответа)

...