Очень часто в статьях по ООП встречается такое слово, как инвариант: ...не позволяет модели обеспечивать собственные инварианты убедиться в выполнении предусловия можно исходя из постусловий и инвариантов предшествующих вызовов Это кстати называется принципом инварианта. собственно инкапсуляция и позволяет сохранять инвариант. То есть независимо от одновременного количества потребителей, она будет сохранять свои инварианты и придерживаться контракта. У каждого агрегата есть корень (Aggregate Root) и граница, внутри которой всегда должны быть удовлетворены инварианты. Что имеется ввиду под этим термином? Как выглядят инварианты в коде? Я нашёл описание термина "инвариант цикла": Инвариант цикла – это соотношение, которое истинно перед циклом, истинно в процессе выполнения цикла и истинно при выходе из цикла. Все это описано у Дейкстры в книге «Дисциплина программирования», и детально разжевано у Гриса в книге «Наука программирования». А хотелось бы понять, что понимают под инвариантом в программировании по контракту и чистом ООП (я так понял, это имеет отношение к инкапсуляции)
Ответ Инвариант в математике - это выражение которое сохраняет свое значение. В программировании инвариантом также называют предикат который всегда истинный. Таким образом, инвариант объекта в ООП - это либо (чаще) условие которое остается истинным после вызова любых методов объекта в любой последовательности, либо (реже) выражение которое сохраняет свое значение после вызова любых методов. В коде инварианты чаще всего никак не выражены, но иногда ставятся защитные проверки которые их проверяют.
Примеры инвариантов. List<>: 0 ≤ _size ≤ _items.Length List<>.Enumerator: list.version = const = version есть защитная проверка List<>.Enumerator: 0 ≤ index ≤ list._size+1 ArraySegment<>: Array = null && Offset = 0 && Count = 0 || Array != null && 0 ≤ Offset && 0 ≤ Count && Offset + Count ≤ Array.Length этот инвариант представлен в коде в виде конструкции Contract.Assert