- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
Основы объектно-ориентированного программирования - Бертран Мейер
Шрифт:
Интервал:
Закладка:
class STACK4 [G] creation
...Как в STACK2...
feature
...Как в STACK2...
invariant
count_non_negative: 0 <= count
count_bounded: count <= capacity
consistent_with_array_size: capacity = representation.capacity
empty_if_no_elements: empty = (count = 0)
item_at_top: (count > 0) implies (representation.item (count) = item)
end
Инвариант класса C это множество утверждений, которым удовлетворяет каждый экземпляр класса во все "стабильные" времена. В эти времена экземпляр класса находится в наблюдаемом состоянии:
[x]. на момент создания экземпляра, сразу после выполнения create a или create a.make(...), где a класса C;
[x]. перед и после каждого удаленного вызова a.r(...) программы r класса С.
Следующий рисунок, показывающий жизнь объектов, поможет разобраться в инвариантах и стабильных временах:
Рис. 11.4. Жизнь объектов
Жизнь объектов не столь уж захватывающая. Вначале - слева на рисунке - он просто не существует. При выполнении инструкции create a или create a.make(...) или clone объект создается и достигает первой станции S1 в своей жизни. Затем идет череда довольно скучных событий: клиенты, для которых доступен объект, один за другим вызывают его компоненты в форме a.f(..). Так все продолжается, пока не завершится вычисление.
Инвариант является характеристическим свойством состояний, представленных большими квадратиками на рисунке: S1, S2, S3 и т.д. Эти состояния соответствуют стабильным временам, упомянутым выше.
Здесь рассматриваются последовательные вычисления, но все идеи легко переносятся на параллельные вычисления, что и будет сделано в соответствующей лекции.Инвариант в момент изменения
Несмотря на свое имя, инвариант не должен выполняться во все времена. Вполне законно, что некоторая процедура g, начиная выполнять свою работу, разрушает инвариант, а, завершая работу, восстанавливает его истинность. В промежуточном состоянии, показанном на рисунке маленьким квадратиком, инвариант не выполняется, но инвариант всегда должен выполняться в заключительном состоянии каждой процедуры. И в человеческом сообществе многие, стараясь сделать что-либо полезное, начинают с того, что разрушают существующий порядок вещей.
Кто должен обеспечить сохранность инвариантов
Квалифицированные вызовы в форме a.f(...), выполняемые на стороне клиента, всегда начинаются и заканчиваются в состоянии, удовлетворяющем инварианту. Подобного правила нет для неквалифицированных вызовов в форме f(...), недоступных для клиентов, но используемых в квалифицированных вызовах для служебных целей. Как следствие, обязанность управлять инвариантами возлагается только на модули, экспортируемые всем клиентам или выборочно. Закрытые методы, недоступные клиентам, не обязаны беспокоиться об инвариантах.
Закончим обсуждение правилом, точно определяющим, когда утверждение является корректным инвариантом класса:
Правило инварианта
Утверждение Inv является корректным инвариантом класса, если и только если оно удовлетворяет следующим двум условиям:
1 Каждая процедура создания, применимая к аргументам, удовлетворяющим ее предусловию в состоянии, в котором атрибуты имеют значения, установленные по умолчанию, вырабатывает заключительное состояние, гарантирующее выполнение Inv.
2 Каждая экспортируемая процедура класса, примененная к аргументам в состоянии, удовлетворяющем Inv и предусловию, вырабатывает заключительное состояние, гарантирующее выполнение Inv.
Заметьте, в этом правиле:
[x]. Предполагается, что каждый класс обладает процедурой создания, задаваемой конструктором по умолчанию, при отсутствии явного ее определения.
[x]. Состояние объекта определяется значениями всех его полей (значениями атрибутов класса для этого конкретного экземпляра).
[x]. Предусловие программы может включать начальное состояние и аргументы.
[x]. Постусловие может включать только заключительное состояние, начальное состояние, (используя нотацию old) и, в случае функций, возвращаемое значение, заданное предопределенной сущностью Result.
[x]. Инвариант может включать только состояние.
Утверждения могут использовать функции, но такие функции фактически являются ссылками на атрибуты - состояние.Математическое выражение правила Инварианта появится позже в этой лекции.
Можно использовать правило Инварианта как основу для ответа на вопрос, что означает нарушение инварианта в период выполнения системы? Мы уже установили, что нарушение предусловия означает ошибку (жучок) клиента, нарушение постусловия - ошибка поставщика. Для инвариантов ответ такой же, как и для постусловий11.2).
Роль инвариантов класса в программной инженерии
Свойство (2) правила инвариантов показывает, что неявно их можно рассматривать как добавления к предусловиям и постусловиям каждой экспортируемой программы класса. Посему принципиально понятие инварианта класса избыточно - это часть предусловий и постусловий программ.
Такое преобразование, конечно, не желательно. Это усложнило бы тексты программ, и, что более важно, - был бы утерян глубокий смысл инварианта, выходящий за пределы отдельных программ, применяемый к классу, как целому. Следует помнить, что инвариант применим не только к уже написанным программам класса, но и к тем, которые еще будут написаны. Он контролирует эволюцию класса, что будет отражено в правилах наследования.
Изменения в ПО неизбежны. Задача в том, чтобы уметь управлять ими. Этот подход соответствует принципам разработки, введенным в начале этой книги. Можно ожидать, что некоторые аспекты программных систем и их компонентов - классов - меняются чаще, чем другие. Добавление, удаление, изменение функциональности явление частое и нормальное. В этом изменчивом процессе все-таки хотелось бы иметь устойчивые свойства, в значительной степени, не подверженные изменениям. Именно эту роль играют инварианты, поскольку в них отражаются фундаментальные соотношения, характерные для класса. Конечно, в программных системах все может изменяться, едва ли можно гарантировать неприкосновенность любого из аспектов системы. Но фундамент остается фундаментом.
Класс STACK2 иллюстрирует базисные идеи, но оценить полную мощь инвариантов можно, лишь ознакомившись со всеми дальнейшими их примерами в остальной части этой книги. Понятие инварианта является одной из наиболее значимых концепций ОО-метода. Только после того, как я написал инвариант, (для разработанного мной класса), только после знакомства и понимания инвариантов (для изучаемого мной класса), только тогда я почувствовал, - я знаю, что такое класс.
Инварианты и контракты
В метафоре контрактов интерпретация инвариантов ясна и понятна. В сообществе людей все контракты часто содержат ссылки на общие правила, регулирующие отношения между партнерами независимо от конкретной области применения контракта. Например правила, установленные для городских зон, справедливы для всех контрактов по строительству жилья. Инварианты класса играют роль общих правил: инвариант класса действует на все контракты между программами класса и клиентами.
Давайте пойдем дальше. Выше отмечалось, что инварианты можно рассматривать как добавки к предусловиям и постусловиям экспортируемых программ. Пусть body тело программы, pre - предусловие, post - постусловие, Inv - инвариант программы. Требование корректности программы может быть записано в виде:
{INV and pre} body {INV and post}
Это означает, что любое выполнение body, начинающееся в состоянии, удовлетворяющем Inv и pre, завершится в состоянии, в котором выполняются Inv и post. Для человека, создающего body, появление инварианта является "хорошей" или "плохой" новостью, облегчается или затрудняется его задача? Ответ, как следует из предыдущих обсуждений, и да и нет! Вспомним ленивого работника, который мечтает о сильном предусловии и слабом постусловии, чтобы можно было бы работать как можно меньше. Инвариант усиливает как предусловие, так и постусловие. Так что, если вы ответственны за реализацию body, то добавление инварианта:
