17. Язык объектных
ограничений OCL. Выражения, типы и операции с типами.
Из языка UML в OCL заимствованы, в первую очередь, следующие концепции:
Для понимания языка OCL существенны определяемые в UML традиционные для
объектных моделей данных различия между объектом некоторого класса и значением
некоторого типа:
В дополнение к скалярным типам данных, заимствованным из UML, в OCL
предопределены структурные типы, которые являются разновидностями типов
коллекций (collection):
В OCL элементами каждого из трех типов коллекций могут быть либо
объекты, либо значения.
Язык OCL предназначен, главным образом, для определения ограничений
целостности данных, соответствующих модели, которая представлена в терминах
диаграммы классов UML. OCL может применяться для определения ограничений,
описывающих пред- и постусловия
операций классов, и ограничений, представляющих собой инварианты классов. При
проектировании реляционных баз данных возможность определения пред- и постусловий операций вряд ли может оказаться
существенной. С точки зрения определения ограничений целостности баз данных
более важны средства определения инвариантов классов.
Под инвариантом класса в OCL понимается условие, которому должны удовлетворять все объекты данного класса. Если говорить более точно, инвариант класса – это логическое выражение, вычисление которого должно давать true при создании любого объекта данного класса и сохранять истинное значение в течение всего времени существования этого объекта. При определении инварианта требуется указать имя класса и выражение, определяющее инвариант указанного класса. Синтаксически это выглядит следующим образом:
context <class_name> inv:
<OCL-выражение>
Здесь <class_name> является именем класса, для которого определяется инвариант, inv – ключевое слово, говорящее о том, что определяется именно инвариант, а не ограничение другого вида, и context – ключевое слово, которое говорит о том, что контекстом следующего после двоеточия OCL-выражения являются объекты класса <class_name>, т. е. OCL-выражение должно принимать значение true для всех объектов этого класса.
Заметим, что OCL является типизированным языком, поэтому у каждого выражения имеется некоторый тип. Естественно, что OCL-выражение в инварианте класса должно быть логического типа.
В общем случае OCL-выражение в определении инварианта основывается на композиции операций, которым посвящена большая часть определения языка. В спецификации языка эти операции условно разделены на следующие группы:
Полагая очевидной семантику предопределенных скалярных типов данных и операций над ними, ограничимся лишь их перечислением. В OCL поддерживаются следующие заимствованные из определения UML скалярные типы данных: Boolean, Integer, Real и String.
В OCL определены три операции над объектами:
Для записи этих трех операций используется «точечная нотация». Например, результатом выражения вида
<объект>.<имя атрибута>
является текущее значение атрибута с именем имя атрибута, если объект имеет такой атрибут. В противном случае использование подобного выражения приводит к возникновению ошибки типа.
Результатом применения к объекту операции перехода по соединению (экземпляру связи-ассоциации) является коллекция, содержащая все объекты, которые ассоциированы с данным объектом через указываемое соединение. Это соединение идентифицируется именем роли, противоположной по отношению к данному объекту. Таким образом, синтаксис выражения перехода по соединению следующий:
<объект>.<имя роли, противоположенной по отношению к объекту>