@majstar_Zubr
C++, C#, gamedev

Отличие терминов Инварианта и Свойства?

Чем отличается понятия инварианта и свойства (неизменного)?

( Корректно ли составлен вопрос?

В чем смысл различия инварианта и спецификации, предъявляемой к классу, который воплощает некую абстракцию из предметной области?
)

Привожу ниже примеры и, возможно, ошибочные суждения:

1) Допустим есть граф, который можно визуально отобразить разными способами (список связей, матрица вершин, перечисление цепочек). Инвариантом графа является ( или корректнее - являЮтся? ) количество вершин и ребер.

2) Допустим есть класс и некая диаграмма классов, которая описывает, что экземпляры этого класса являются персистентными. Класс, к тому же, принадлежит некой иерархии наследования, в которой уровни наследования отсчитываются натуральными числами. Тогда:
  • Инвариантом класса уровня наследования 1 является неприватный интерфейс базового класса.
  • Инвариантом класса уровня наследования 2 является неприватный интерфейс конкретного класса-родителя из уровня наследования 1.


3) Допустим, есть контейнер с неотсортированными элементами. Есть класс, конструктор которого принимает контейнер, и есть метод, реализующий сортировку и вызываемый в конструторе. Тогда корректно утверждать, что класс обеспечивает инвариант для отсортированного контейнера.

4) "Куча имеет свойство упорядоченности элементов по невозрастанию" (эквивалентно) "Класс, реализующий абстрактную структуру данных куча, обеспечивает инвариант упорядоченности элементов по невозрастанию"

Пожалуйста, разъясните допущенные ошибки, я сомневаюсь, что я правильно понял концепцию.
Спасибо за внимание.
  • Вопрос задан
  • 1453 просмотра
Решения вопроса 1
@res2001
Developer, ex-admin
Из википедии:
Инвариант в объектно-ориентированном программировании — выражение, определяющее непротиворечивое внутреннее состояние объекта.

Но это относится не только к ООП, а в принципе.
Из ваших примеров, по моему, только 4 про инвариант.

Исходя из определения из вики, инвариант - логическое выражение (а не свойство), которое всегда должно выполняться для объекта. Если оно не выполняется, то объект (класс, структура и т.п.) находится в несогласованном состоянии и его дальнейшее использование опасно.
Обычно инварианты нарушаются внутри методов класса, при выходе из метода инвариант должен снова восстанавливаться, иначе метод отработал не правильно.
Простой пример: для Си строки инвариант - не нулевой указатель на начало и символ 0 в конце строки.
Например у вас есть функция AddString, которая добавляет к существующей строке другую строку. Для простоты предположим, что не нужно перевыделять память. В процессе выполнения AddString инвариант нарушается - 0 символ заменяется добавляемыми символами второй строки. Но после добавления нулевой символ должен быть восстановлен в конце, после чего инвариант снова будет истинным.

Для одного объекта может быть несколько инвариантов, для разных методов объекта могут быть важны не все инварианты. Если метод в ходе своей работы нарушает какой-то инвариант, есть смысл в начале и конце метода проверить этот инвариант с помощью assertа. Это предотвратит возможные ошибки.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы