С позиции Проектирования по Контракту, инварианты классов - это ограничения общего характера, применимые и к подрядчикам, и к клиентам. Правило родительских инвариантов отражает тот факт, что все подобные ограничения передаются субподрядчикам.
Свое истинное значение для ОО-разработки наследование приобретает лишь совместно с утверждениями и двумя приведенными выше правилами. Метафора контрактов и субподрядов - прекрасная аналогия, помогающая разрабатывать корректное ОО-ПО. Несомненно, в этом - одна из центральных идей теории проектирования.
Абстрактные предусловия
Правило ослабления предусловий может оказаться чересчур жестким в случае, когда наследник понижает уровень абстракции, характерный для его предка. К счастью, есть легкий обходной путь, полностью согласующийся с теорией.
Типичным примером этого является порождение
В общем понятии стека нет понятия емкости. Поэтому создается впечатление, будто при переходе к
Ответ становится очевиден, если мы ближе познакомимся с требованиями к клиенту. То, что нужно сохранить или ослабить, не обязательно является конкретным предусловием, как оно видится в реализации поставщика (реализация это его забота), но касается предусловия, как оно видится клиенту. Пусть процедура
put (x: G) is
-- Поместить x на вершину.
require
not full
deferred
ensure
...
end
где функция
full: BOOLEAN is
-- Заполнено ли представление стека?
-- (По умолчанию, нет)
do Result := False end
Тогда в
full: BOOLEAN is
-- Заполнено ли представление стека?
-- (Да, если число элементов равно емкости стека)
do Result := (count = capacity) end
Предусловие, такое как not full, включающее свойство, которое переопределяется потомками, называется абстрактным (abstract) предусловием.
Такое использование абстрактных предусловий для соблюдения правила Утверждения Переобъявления может показаться обманом, однако это не так. Несмотря на то, что конкретное предусловие фактически становится более сильным, абстрактное предусловие не меняется. Важно не то, как реализуется утверждение, а то, как оно представлено клиентам в интерфейсе класса (краткой или плоско-краткой форме). Предваренный условием вызов
if not s.full then s.put (a) end
будет корректен независимо от вида
Впрочем, есть доля справедливой критики этого подхода, так как он вступает в противоречие с принципом Открыт-Закрыт. При проектировании класса
[x]. ограниченный стек является стеком;
[x]. в стек всегда можно добавить еще один элемент.
Если предпочесть первое свойство и допускать порождение
Было бы ошибкой включить в виде постусловия подпрограммы |
Правило языка
Правило Утверждений Переобъявления, так как оно сформулировано, является концептуальным руководством. Как преобразовать его в безопасное и проверяемое правило языка?
Вильям Л Саймон , Вильям Саймон , Наталья Владимировна Макеева , Нора Робертс , Юрий Викторович Щербатых
Зарубежная компьютерная, околокомпьютерная литература / ОС и Сети, интернет / Короткие любовные романы / Психология / Прочая справочная литература / Образование и наука / Книги по IT / Словари и Энциклопедии