Инвариант, эквивалентный True, является тривиальным. К тривиальным относится и любое свойство, предполагающее инициализацию полей значениями по умолчанию (ноль для числовых переменных, False — для булевских, Void — для ссылок).
Даже в случае отсутствия сильных инвариантов может быть полезно обеспечить в классе процедуры создания, позволяющие клиентам комбинировать создание с инициализацией полей. Класс POINT, описывающий точки на плоскости, может предоставить клиентам процедуры создания make_cartesian и make_polar, каждая с двумя аргументами, обозначающими координаты точки. Клиент может задать точку, указав либо декартовы координаты, либо — полярные координаты точки.
В некоторых случаях, POINT является тому примером, можно допускать обе формы создания пример 6.1 и пример 6.3. Этот случай описывается следующим образом:
class POINT create default_create, make_cartesian, make_polar feature … end
Здесь default_create — это имя метода (наследуемого всеми классами от общего предка) без аргументов, который по умолчанию помимо основной работы ничего больше не делает. Чтобы использовать эту процедуру, можно написать:
create your_point.default_create
Это можно выразить короче, в форме пример 6.1:
create your_point
Эта форма является корректной наряду с другими формами:
create your_point.make_cartesian (x, y) create your_point.make_polar (r, t)
Общее правило таково:
create default_create
create x.default_create
Так что концептуально можно полагать, что каждый класс имеет процедуру создания, необходимую для создания его экземпляров. Чтобы полностью построить build_a_line, нам осталось уточнить последнюю строку псевдокода: — "Create fancy_line". Это соответствует вызову еще одного оператора создания
create fancy_line.make_metro ("FANCY"
Здесь используется make_metro — одна из процедур создания класса LINE, которая создает линию метро, принимая в качестве аргумента имя этой линии, принадлежащее строковому типу.
Так как все это доступно как часть предопределенных примеров, то хорошая идея — пойти и прочесть окончательный текст.
Рассмотрите текст build_a_line в классе LINE_BUILDING и убедитесь, что вы все прекрасно понимаете.
Как следствие предшествующего обсуждения, следует помнить, что необходимо создание объекта.
create x.make (...)
В соответствии с принципами Проектирования по Контракту для каждого изучаемого оператора мы должны точно знать:
Помимо этого, классы (и циклы, как вскоре увидим) имеют инварианты, которые описывают свойства, сопровождающие выполнение операций.
Совместно свойства контракта определяют корректность любого программного механизма.
Приведем соответствующее правило для механизма создания.
Для корректности оператора создания перед его выполнением должно выполняться:
предусловие процедуры создания.
Следующие свойства должны иметь место после выполнения оператора создания, вызванного целью x типа С;
Если процедура создания не указана, то базисная форма create x тривиально удовлетворяет свойствам 1 и 3, поскольку не имеет ни предусловия, ни постусловия.
Предусловие процедуры создания (предложение 1) не требует, чтобы x имел значение void. Не является ошибкой последовательно создать два объекта с одной и той же целью x:
create x -После создания x не является void (смотри предложение 2) create x
Этот специфический пример полезен для понимания, хотя с содержательной точки зрения имеет изъян, поскольку объект, созданный первым оператором, будет немедленно забыт при выполнении второго оператора:
Второй оператор создания перенаправит ссылку на второй объект, так что первый объект станет бесполезным (вскоре мы поговорим подробнее о таких сиротливых объектах, не присоединенных ни к одной сущности).
Хотя два последовательных оператора создания в предыдущем примере не имеют смысла, варианты этой схемы могут быть полезными. Например, тогда, когда между операторами создания выполняются другие операторы, выполняющие полезные операции над первым объектом. Возможно, после создания первый объект будет куда-нибудь передан в качестве аргумента или записано его состояние.
Предложения со 2-го по 4-е определяют эффект выполнения оператора создания.
Если инициализация по умолчанию не обеспечивает инвариант, то в обязанность процедуры создания входит корректировка ситуации таким образом, чтобы в итоге инвариант выполнялся.