Здавалка
Главная | Обратная связь

Операции union, intersect, symmetricDifference



Параметрами двуместных операций union, intersect, symmetricDifference являются две коллекции, причем в OCL операции определены почти для всех возможных комбинаций типов коллекции. Не будем рассматривать все определения этих операций и

63 Для коллекций значений возможно также применение операций min, max и avg, выдающих минимальное, максимальное и среднее значение элементов коллекции соответственно.

кратко упомянем только две из них. Результатом операции union, определенной над множеством и мультимножеством, является мультимножество, т. е. из результата объединения таких двух коллекций дубликаты не исключаются. Результатом же операции union, определенной над двумя множествами, является множество, т. е. в этом случае возможные дубликаты должны быть исключены.

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

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


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

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

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

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

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

context Отдел inv:self.номер 5 or self.служащий select (возраст 30) size () = 0

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

Тот же инвариант можно сформулировать в контексте класса Сотрудник:

context Сотрудник inv:self.возраст > 30 or self.отдел.номер 5

Здесь следует обратить внимание на подвыражение self.отдел.номер 5. Поскольку отдел – это имя роли соединения, значением подвыражения self.отдел является коллекция (множество). Но кратность роли отдел равна единице, т. е. каждому объекту служащего соответствует в точности один объект отдела. Поэтому в OCL допускается сокращенная запись операции self.отдел.номер, значением которой является номер отдела текущего служащего.

Пример 11.3. Определить ограничение, в соответствии с которым у каждого отдела должен быть менеджер, и любой отдел должен быть основан не раньше соответствующей компании:

context Отдел inv:self.служащий exists (должность = "manager") and self.компания.годОснования self.годОснования

Здесь должность – атрибут класса Служащий, а атрибуты с именем годОснования имеются и у класса Отдел, и у класса Компания. В условном выражении этого инварианта подвыражение self.служащий exists (должность = "manager") эквивалентно выражению self.служащий select (должность = "manager") size () > 1. Если бы в ограничении мы потребовали, чтобы у каждого отдела был только один менеджер, то следовало бы написать ... size () = 1, и это было бы не эквивалентно варианту с exists.

Обратите внимание, что в этом случае снова законным является подвыражение self.компания.годОснования, поскольку кратность роли компания в ассоциации классов Отдел и Компания равна единице.

Пример 11.4. Условие четвертого инварианта ограничивает максимально возможное количество служащих компании числом 1000:

context Компания inv:self.отдел collect (служащие) size ( ) < 1000

Здесь полезно обратить внимание на использование операции collect. Проследим за вычислением условного выражения. В нашем случае в классе Компания всего один объект, и он сразу становится текущим. В результате выполнения операции self.отдел будет получено множество объектов, соответствующих всем отделам компании. При выполнении операции collect (служащие) для каждого объекта-отдела по соединению с объектами класса СЛУЖАЩИЕ будет образовано множество объектов-служащих данного отдела, а в результате будет образовано множество объектов, соответствующих всем служащим всех отделов компании, т. е. всем служащим компании.







©2015 arhivinfo.ru Все права принадлежат авторам размещенных материалов.