Связь OCL при работе между двумя классами

У меня есть диаграмма классов, и мне нужно написать об этом OCL, но я не уверен в правильном синтаксисе. Я много искал, но нашел много разных способов, поэтому я хотел бы знать, правильно ли я их напишу. Например, на моем компакт-диске у меня есть классы Ticket и Event, связанные ролью «ticket validFor event». Билет имеет атрибут цены с плавающей запятой. Правильно ли писать OCL для расчета общего количества входящих событий?

CONTEXT Event::totalIncoming():float
post result=ticket.allInstances()->select(t : t.validFor=self)->collect(price)->sum()

Я беру все экземпляры билетов, выбираю все экземпляры, действительные для мероприятия, собираю их цены и, наконец, суммирую их. Я думаю, что всей информации, которую я предоставил, достаточно, но если вам нужно больше, пожалуйста, сообщите мне. Спасибо


person spx305    schedule 05.10.2018    source источник


Ответы (1)


В приведенном вами примере используется полный OCL; самостоятельный текстовый документ, часто с расширением файла *.ocl, в котором основному выражению OCL дается окружающий контекст, как указано в разделе 12 спецификации OCL: «Использование выражений OCL в моделях UML». Этот подход полезен, если вы хотите разделить свои ограничения и задачи модели и/или использовать утилиту массового редактирования текста.

В качестве альтернативы вы можете использовать инструмент, предоставляющий текстовое поле для каждого ограничения UML. В этом случае вы часто вводите просто выражение Essential OCL, которое инструмент соответствующим образом оборачивает как Constraint.body.

Если вы работаете с Ecore, вы можете использовать OCLinEcore для встраивания основных выражений OCL в файлы *.ecore или *.oclinecore.

Ваш пример неверен в том, что вы должны использовать строчные буквы «контекст» и «:» и, возможно, имя после «сообщения».

Ваш пример, вероятно, неверен, поскольку вы используете «билет», а не «билет» в качестве имени класса.

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

Однако, возможно, вы имели в виду «билет» как переменную-член коллекции, и в этом случае allInstances() неверен. "ticket->select(...)" достаточно, чтобы выбрать часть коллекции билетов.

Я подозреваю, что подойдет "result = ticket->select(validFor=self).price->sum()". Однако обратное тестирование validFor может быть избыточным, поскольку прямой навигации часто достаточно с проверкой обратной избыточной навигации.

person Ed Willink    schedule 06.10.2018