Введение в реляционные базы данных


Примеры инвариантов


В заключение обзора языка OCL приведем примеры четырех инвариантов, выраженных на этом языке. Будем основываться на диаграмме классов, показанной на рис. 10.14.


Рис. 10.14.  Диаграмма классов, используемая для примеров на языке OCL

context Служащий inv: self.возраст >18 and self.возраст < 100

Пример 10.1. Определить ограничение «возраст служащих должен быть больше 18 и меньше 100 лет». (html, txt)

Условие инварианта накладывает требуемое ограничение на значения атрибута возраст, определенного в классе Служащий. В условном выражении инварианта ключевое слово self обозначает текущий объект класса-контекста инварианта. Можно считать, что при проверке данного условия будут перебираться существующие объекты класса Служащий, и для каждого объекта будет проверяться, что значения атрибута возраст находятся в пределах заданного диапазона. Ограничение удовлетворяется, если условное выражение принимает значение true для каждого объекта класса-контекста.

context Отдел inv: self.номер

5 or self.служащий
select (возраст
30)
size () = 0

Пример 10.2. Выразить на языке OCL ограничение, в соответствии с которым в отделах с номерами больше 5 должны работать сотрудники не старше 30 лет. (html, txt)

В этом случае условное выражение инварианта будет вычисляться для каждого объекта класса Отдел. Подвыражение справа от операции or вычисляется слева направо. Сначала вычисляется подвыражение self.служащий, значением которого является множество объектов, соответствующих служащим, которые работают в текущем отделе. Далее к этому множеству применяется операция select (возраст 30), в результате которой вырабатывается множество объектов, соответствующих служащим текущего отдела, возраст которых не превышает 30 лет. Значением операции size () является число объектов в этом множестве. Все выражение принимает значение true, если последняя операция сравнения «=0» вырабатывает значение true, т. е. если в текущем отделе нет сотрудников младше 31 года. Ограничение в целом удовлетворяется только в том случае, если значением условия инварианта является true для каждого отдела.




Тот же инвариант можно сформулировать в контексте класса Сотрудник:
context Сотрудник inv: self.возраст > 30 or self.отдел.номер < 5
Здесь следует обратить внимание на подвыражение self.отдел.номер > 5. Поскольку отдел – это имя роли соединения, значением подвыражения self.отдел является коллекция (множество). Но кратность роли отдел равна единице, т. е. каждому объекту служащего соответствует в точности один объект отдела. Поэтому в OCL допускается сокращенная запись операции self.отдел.номер, значением которой является номер отдела текущего служащего.
context Отдел inv: self.служащий
exists (должность = "manager") and self.компания.годОснования
self.годОснования
Пример 10.3. Определить ограничение, в соответствии с которым у каждого отдела должен быть менеджер, и любой отдел должен быть основан не раньше соответствующей компании: (html, txt)
Здесь должность – атрибут класса Сотрудники, а атрибуты с именем годОснования имеются и у класса Отдел, и у класса Компания. В условном выражении этого инварианта подвыражение self.служащий
exists (должность = "manager") эквивалентно выражению self.служащий
select (должность = "manager")
size () >= 1. Если бы в ограничении мы потребовали, чтобы у каждого отдела был только один менеджер, то следовало бы написать ... size () = 1, и это было бы не эквивалентно варианту с exists.
Обратите внимание, что в этом случае снова законным является подвыражение self.компания.годОснования, поскольку кратность роли компания в ассоциации классов Отдел и Компания равна единице.
context Компания inv: self.отдел
collect (служащие)
size ( ) < 1000
Пример 10.4. Условие четвертого инварианта ограничивает максимально возможное количество сотрудников компании числом 1000: (html, txt)
Здесь полезно обратить внимание на использование операции collect. Проследим за вычислением условного выражения. В нашем случае в классе Компания всего один объект, и он сразу становится текущим. В результате выполнения операции self.отдел будет получено множество объектов, соответствующих всем отделам компании.При выполнении операции collect (служащие) для каждого объекта-отдела по соединению с объектами класса СЛУЖАЩИЕ будет образовано множество объектов-служащих данного отдела, а в результате будет образовано множество объектов, соответствующих всем служащим всех отделов компании, т. е. всем служащим компании.

Содержание  Назад  Вперед