Это третья статья цикла, посвященного разработке, управляемой моделями. В предыдущих статьях мы разбирались с OCL и метамоделями, создавали свою метамодель для языка Anchor с древовидным редактором. Сегодня сделаем редактор Anchor-диаграмм.

Краткое содержание


В нескольких словах: в статье описывается как создавать редакторы диаграмм. Причём, описывается очень детально. Если вы не планируете заниматься этим прямо сейчас, то рекомендую просто пролистать статью, посмотреть картинки, заголовки — не вчитываться слишком сильно.

Если вы хотите и можете уделить этому немного больше времени, то тут есть готовый проект. Можете установить Eclipse и попробовать всё вживую.

Если вы готовы отложить все свои дела и прямо сейчас заняться созданием редактора диаграмм, то ниже для вас есть детальное пошаговое руководство.

Введение


Важно отметить, что метамодель языка Anchor из предыдущей статьи синтаксически нейтральна. В ней описаны только понятия, используемые при построении Anchor-моделей. Но не описано, как именно эти понятия можно рисовать на диаграммах или описывать в виде текста.

Также в предыдущей статье параллельно с синтаксически нейтральной метамоделью мы создали древовидный редактор Anchor-моделей, в котором для абстрактных понятий используется уже совершенно конкретное представление в виде дерева с иконками.

Если вы загляните в anchor-файл с некоторой Anchor-моделью, то увидите ещё одну нотацию, но уже не древовидную, а текстовую.

Java API, которое мы также сгенерировали в прошлой статье работает уже с третьим представлением Anchor-моделей в виде Java-объектов.

В данной статье мы опишем ещё одну нотацию для Anchor-моделей – диаграммную. Для создания редактора диаграмм, как и раньше, будем использовать Eclipse Modeling Tools. Есть несколько инструментов, позволяющих работать с диаграммами.

Graphical Editing Framework (GEF)

GEF – это достаточно мощный инструментарий для Eclipse, позволяющий работать с различными диаграммами, графами. Особенно хороша актуальная на текущий момент 4-ая версия, в которой есть поддержка DOT и много разных интересных вещей. Недостаток GEF заключается в том, что нужно знать Java и писать много типового кода, который вполне можно было бы сгенерировать автоматически.

Graphiti

Лично им не пользовался и не видел примеры. Но, на сколько я понимаю, это некоторая кроссплатформенная абстракция над GEF-подобными инструментариями, которая, правда, на текущий момент ничего кроме GEF не поддерживает :-)

Graphical Modeling Framework (GMF)

GMF – это инструментарий, который несколько упрощает использование GEF для диаграмм, основанных на EMF. Он состоит из 3-х частей: GMF Notation, GMF Tooling и GMF Runtime.

GMF Notation – метамодель для представления (произвольных) диаграмм.

GMF Runtime – повторно используемые компоненты для редакторов диаграмм (панели инструментов, функциональность экспорта диаграмм в различные графические форматы и т.п.).

GMF Tooling – инструментарий, который позволяет генерировать код для редактора диаграмм. Работа с GMF Tooling обычно выглядит так.

  • Создаёте Ecore-метамодель для некоторого языка моделирования.
  • Создаёте .gmfgraph модель с описанием графических элементов, которые будут использоваться на диаграммах.
  • Создаёте .gmftool модель с описанием панели инструментов редактора диаграмм.
  • Создаёте .gmfmap модель, которая связывает 3 этих модели между собой :-)
  • И, наконец, генерируете исходный код редактора диаграмм.

Все эти дополнительные модели в GMF очень напоминают .genmodel модель, которую мы использовали в прошлой статье для генерации древовидного редактора диаграмм. Наверное, это проще, чем использовать GEF напрямую, но всё-равно достаточно сложно.

GMF Notation и GMF Runtime используются практически во всех редакторах диаграмм, созданных на базе Eclipse.

Для GMF Tooling есть альтернативы. Однако, стоит отметить, что GMF появился относительно давно и работает в том числе и в старых версиях Eclipse. Например, Rational Software Architect обычно основан на достаточно древней версии Eclipse. Поэтому если вы хотите создать редактор диаграмм для RSA, придётся использовать GMF Tooling, вместо более современных инструментов. Пример такого редактора диаграмм вы видели в первой статье цикла (обратите внимание на диаграмму с человечками, тут доступен исходный код).

Примечание

Вообще, тот же Sirius теоретически должен работать начиная с Eclipse Juno, но честно говоря я пока не пробовал.

Sirius

Sirius, как и GMF Tooling, позволяет создавать редакторы диаграмм на основе GMF Notation и GMF Runtime. Но он гораздо проще, функциональней и удобней.

  • Создаётся только одна модель, описывающая редактор диаграмм, а не 3.
  • Кроме представления модели в виде диаграммы он поддерживает древовидное, табличное и другие представления.
  • Поддерживается валидация моделей, навигация между представлениями, фильтры и т.п.
  • Не нужно генерировать никакой код. Вы описываете редактор диаграмм и в этом же экземпляре Eclipse сразу же его тестируете.

EuGENia

На базе Eclipse создано достаточно большое количество инструментов, которые можно использовать при разработке, управляемой моделями. Инструменты совершенно разные: для преобразования, валидации, сравнения, объединения моделей и т.д. В проекте Epsilon разработчики попытались как-то унифицировать и состыковать между собой все эти технологии.

EuGENia – это инструмент, используемый в Epsilon для разработки редакторов диаграмм. Фактически это обёртка над GMF Tooling, которая несколько упрощает создание .gmfgraph, .gmftool и .gmfmap моделей.

Настройка


Мы будем создавать редактор диаграмм, основанный на Ecore-метамодели, описанной в предыдущей статье. Соответственно использовать чистый GEF или Graphiti нет смысла, нужно брать какую-нибудь надстройку, заточенную под EMF. EuGENia отпадает, потому что мы пока не будем использовать Epsilon. GMF Tooling тоже отпадает, потому что, с одной стороны, он слишком сложный, а с другой – нам не нужно, чтобы редактор диаграмм работал в старых версиях Eclipse. Остаётся Sirius.

Установите Eclipse Modeling Tools.

Установите Sirius. Для этого выберите в меню Help -> Install New Software… Добавьте сайт http://download.eclipse.org/sirius/updates/releases/3.0.0/mars

Примечание

На момент написания статьи это последняя версия Sirius. Актуальный список версий доступен тут.

Выберите и установите компоненты, отмеченные на рисунке.



Возьмите проекты из прошлой статьи. Разверните их в текущей рабочей области. Для этого в меню выберите File -> Export… -> Deployable plugin-ins and fragments.



Отметьте проекты anchor, anchor.edit и anchor.editor. Выберите Install into host. Repository. После развёртывания плагина перезапустите Eclipse.

В предыдущей статье описаны ещё два варианта запуска этих плагинов в Eclipse (запуск второго экземпляра и копирование jar-файлов в $ECLIPSE_HOME/dropins).

Убедитесь, что у вас открываются тестовые модели из проекта anchor.tests папки model.



После этого желательно удалить проекты anchor, anchor.edit и anchor.editor из рабочей области, потому что они уже развёрнуты. Если вы их оставите, то не будет ничего фатального. Возможно, при автодополнении будут выдаваться дублирующиеся метаклассы (один из рабочей области, второй из развёрнутого плагина).

Создание проекта


Вообще проект anchor.design уже создан. Вы можете

  • удалить этот проект и создать свой,
  • создать аналогичный проект рядом,
  • ничего не создавать и посмотреть всё на примере готового проекта.

Для создания проекта выберите File -> New -> Other… -> Sirius -> Viewpoint Specification Project. Назовите его anchor.design или ещё как-то.

Откройте перспективу Sirius (Window -> Perspective -> Open Perspective).



В проекте минимум файлов: несколько стандартных файлов с настройками, активатор плагина в папке src и, самое главное, файл anchor.odesign. В нём мы будем описывать элементы диаграмм, панель инструментов редактора диаграмм и всё остальное.

Создание точки зрения


На одну и ту же модель может быть несколько точек зрения (заказчика или разработчика, концептуальная, логическая или физическая и т.д.). Мы будем описывать только одну точку зрения (Viewpoint). Добавьте её через контекстное меню в древовидном редакторе. Присвойте ей идентификатор Anchor, в поле Model File Extension укажите anchor.



Примечание

Лично меня очень смущает, что в Sirius у объектов нужно вручную прописывать идентификаторы, они вполне могли бы присваиваться автоматически. Смущает возможность изменения идентификаторов.

Также смущает привязка редактора диаграмм к моделям по расширению файла модели, а не по пространству имен.

Но, в принципе, оно работает, и ладно.

Создание представления


У модели может быть множество различных представлений. На текущий момент Sirius поддерживает 5 представлений (диаграмма, таблица, сводная таблица, дерево, диаграмма последовательностей). В данной статье мы будем работать только с диаграммами.

Добавьте в точку зрения Anchor представление модели в виде диаграммы (New Representation -> Diagram Description).



В свойствах укажите идентификатор Anchor Diagram, в поле Domain Class укажите корневой объект модели (anchor.Model). В этом поле, как и во многих других полях, работает автодополнение, вызываемое по Ctrl + Space.

Обратите внимание на то, что в представлении автоматически создан слой Default для размещения элементов диаграмм. В данной статье мы не будем создавать дополнительные слои.

Спецификация визуальных элементов для якорей


Теперь необходимо описать узлы и ребра, из которых будут строиться диаграммы.

Примечание

Ещё раз отмечу, что в предыдущей статье в файле anchor.ecore мы описали язык Anchor в синтаксически нейтральном виде. Описали только концепты, из которых состоят Anchor-модели. Эти концепты могут быть представлены в виде элементов диаграммы, в виде узлов дерева, в виде текста. Сейчас мы фактически создаём вторую модель, в которой описываем как синтаксически нейтральные концепты Anchor-моделей должны быть визуализированы.

Очень важно понимать разницу между моделью и диаграммой.

В слой Default добавьте узел (Node) для якорей с идентификатором Anchor. В поле Domain Class напишите anchor.Anchor. В поле Semantic Candidates Expression необходимо указать где именно в модели необходимо искать якоря. Нажмите Ctrl + Space и посмотрите какие варианты доступны:

  • var: означает, что нужно взять значение некоторой переменной;
  • feature: означает, что нужно взять некоторое свойство или ассоциацию текущего объекта (в данном случае текущий объект – это корневой объект модели типа anchor.Model);
  • service: означает, что нужно запустить некоторый Java-метод, который вернёт список якорей, которые нужно отображать на диаграмме;
  • aql: означает, что нужно выполнить некоторое AQL-выражение, которое вернёт список объектов (AQL очень похож на OCL, и если вы читали эту статью, то он должен быть для вас совершенно понятен);
  • [/] аналогично позволяет написать некоторое выражение, которое будет интерпретировано движком Acceleo (однако это работает медленно, неустойчиво и сложно, рекомендуется использовать AQL);
  • ocl: означает, что нужно выполнить некоторое OCL-выражение, которое вернёт список объектов (в данной статье мы будем использовать преимущественно OCL-выражения, честно говоря, я не очень понимаю чем OCL и AQL принципиально отличаются, но всё-таки OCL – это стандарт OMG).

В данном случае якоря, которые необходимо отображать на диаграмме, доступны через ассоциацию anchors корневого объекта модели. Поэтому в поле Semantic Candidates Expression необходимо написать feature:anchors.

Примечание

Если вы не понимаете о какой ассоциации идёт речь, посмотрите на последнюю диаграмму в предыдущей статье.



Теперь необходимо описать как именно якоря должны изображаться на диаграммах. Если вы создавали новый проект, то скопируйте в него папку icons. Кликните в Model Explorer слева на проект anchor.design и нажмите F5 (либо выберите в контекстном меню Refresh). После этого папка icons должна появиться в Eclipse.

Добавьте в описание узла Anchor ссылку на изображение (New Style -> Workspace Image). В свойствах укажите /anchor.design/icons/Anchor.png.

Тестирование редактора диаграмм


Итак, один элемент диаграммы мы уже описали, посмотрим, как всё это выглядит. В проекте anchor.tests в папке model лежат тестовые модели с диаграммами. Если вы создаёте новый проект anchor.design, то эти диаграммы открыть не получится, потому что в них много объектов, которые мы ещё не описали в файле anchor.odesign. Поэтому вы можете просто удалить файл Pefrormance.aird и создать новый (сама тестовая модель при этом никуда не денется, потому что она лежит в anchor-файле). Для создания новой диаграммы выберите File -> New -> Representations File. Выберите Initialization from a semantic resource. Выберите модель.



На последней вкладке мастера создания диаграммы укажите папку anchor.tests/model. Выберите точку зрения Anchor.

В созданном файле пока нет диаграмм. Чтобы создать одну выберите корневой объект модели и нажмите New Representation -> new Anchor Diagram.



Перетащите окно редактора диаграммы вправо, чтобы одновременно видеть и описание редактор диаграмм anchor.odesign, и тестовую диаграмму.



Диаграмма выглядит немного странно :-)

Это связано с тем, что на ней отображаются две иконки. Одна из проекта anchor.design, вторая из проекта anchor.edit (который мы создавали в прошлой статье для древовидного редактора). Иконки для древовидного редактора мелковаты и немного корявые, потому что получены путем преобразования из svg- в gif-формат. Чтобы их убрать с диаграммы в anchor.odesign в свойствах изображения на вкладке Label снимите галочку Show Icon.

Также в поле Label Position укажите border. Это значит, что подпись якоря должна отображаться не внутри иконки якоря, а на её границе.

Обратите внимание на то, что в поле Label Expression указано feature:name. Это значит, что в качестве подписи будет использоваться свойство name якоря.

На вкладке Advanced в поле Allow resizing запретите изменение размера иконки.

Теперь сохраните спецификацию редактора диаграмм (Ctrl + S) и, о чудо, диаграмма автоматически обновится. В этом плане Sirius очень упрощает разработку редакторов диаграмм. Например, в предыдущей статье приходилось генерировать исходный код, запускать второй экземпляр Eclipse. То же самое приходится делать при использовании GMF Tooling, а тут всё просто.



Спецификация визуальных элементов для атрибутов


Для атрибутов можно было бы описать визуальный элемент так же как и для якорей, выбрав метакласс anchor.Attribute и соответствующую иконку. Однако всё несколько сложнее.

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

Во-вторых, когда вы начнёте описывать визуальные элементы для связей, то увидите, что для них указывается какие узлы диаграммы они могут связывать. Например, с узлом (Knot) можно связывать только KnottedStaticAttribute и KnottedHistorizedAttrbute. А StaticAttribute и HistorizedAttrbute связывать с узлом нельзя, у них банально в метамодели не определено отношение с узлом (anchor.Knot).

Поэтому скопируйте описание визуального элемента для Anchor четыре раза для каждого вида атрибутов. Измените соответствующим образом поля Id и Domain Class. Очистите поле Semantic Candidates Expression, потому что атрибуты не являются объектами верхнего уровня, они принадлежат якорям, а не модели напрямую. Можно было бы написать OCL-выражение, которое обходит все якоря и возвращает все атрибуты, но в этом нет смысла. Также измените иконки. После сохранения спецификации и упорядочивания объектов (перетаскиванием мышкой) вы увидите что-то подобное.



Спецификация связей между якорями и атрибутами


Между метаклассами anchor.Anchor и anchor.Attribute определено отношение attributes. Для каждого экземпляра этого отношения нам нужно на Anchor-диаграммах рисовать линию. Для этого добавьте в слой Default ребро, основанное на отношении (New Diagram Element -> Relation Based Edge).

Укажите идентификатор AttributeEdge. В поле Source Mapping укажите визуальный элемент Anchor, который используется для рисования якорей. В поле Target Mapping укажите 4 визуальных элемента для различных видов атрибутов. В поле Target Finder Expression укажите feature:attributes.

В стилях ребра (Edge Style) на вкладке Decorators отметьте для обоих концов NoDecoration. На вкладке Advanced в поле Ends Centering отметьте Both, чтобы концы линий выравнивались по центру узлов, которые они соединяют. Также удалите вложенный элемент Label, потому что тут не нужны подписи.

После сохранения и упорядочивания элементов вы увидите нечто подобное. Упорядочивать придётся мышкой, из коробки автоматическое упорядочивание работает не очень.



Спецификация визуальных элементов для скреп и узлов


Это вы уже можете сделать самостоятельно. Для узлов укажите метакласс anchor.Knot, а в поле Semantic Candidates Expression укажите feature:knots. Для скреп, как и для атрибутов, создайте 4 элемента. В поле Semantic Candidates Expression укажите feature:ties. На вкладке Label для скреп очистите поле Label Expression, потому что у них нет имён.

Добавьте связь между KnottedStaticAttribute, KnottedHistorizedAttribute и Knot по аналогии со связью между якорями и атрибутами.

Примечание

Если у вас не будут отображаться на диаграмме какие-то связи или что-то не будет работать, попробуйте провалидировать спецификацию. Для этого нажмите кнопку с зелёной галочкой в шапке редактора спецификаций.

Например, я вместо feature:knot, написал feature:knots. При этом связи между атрибутами и узлами просто не отображались без каких-либо сообщений об ошибках. После валидации спецификации становится ясно в чём проблема. Ещё одна из частых ошибок – это лишние пробелы.

В итоге вы получите что-то такое.



Спецификация связей скреп c якорями и узлами


Этот вид связей уже несколько сложнее тех, которые мы создавали ранее. Это обусловлено тем, что они основаны не на отношении между объектами, а на экземплярах метакласса anchor.AnchorRole, у которых есть два свойства (имя и флаг, определяющий является ли это отношение идентифицирующим) и две ассоциации (со скрепой и якорем).

Добавьте Element Based Edge с идентификатором AnchorRoleEdge и следующими свойствами:

  • Domain Class – anchor.AnchorRole
  • Source Mapping – StaticTie, KnottedStaticTie, HistorizedTie, KnottedHistorizedTie
  • Source Finder Expression – feature:tie
  • Target Mapping – Anchor
  • Target Finder Expression – feature:anchor

Как и раньше, сделайте линию без стрелочек, отцентрируйте концы линии, уберите галочку на Show Icon у подписей.

В отличие от предыдущих связей на этой будем отображать две подписи. По центру линии нужна подпись с названием роли, для этого в поле Label Expression укажите feature:name. Ещё добавьте Begin Label Style, в поле Label Expression напишите ocl:if self.isIdentifier then '1' else 'm' endif. Вот, нам внезапно и пригодился OCL. Смысл выражения, я думаю, интуитивно понятен: если отношение идентифицирующее, показываем 1, иначе – m.

По аналогии добавьте связи, основанные на метаклассе anchor.KnotRole. В итоге, вы увидите что-то такое. Обратите внимание на то, что в окне свойств можно изменять как свойства объектов модели, так и различные аспекты отображения этих объектов на диаграммах.



Ну, что же, редактор диаграмм почти готов. Конечно он не так красив и удобен как на сайте Anchor Modeling. Считайте это платой за использование типового решения. Хотя то, что свойства отображаются в том же окне, по-моему, достаточно удобно. В любом случае, всё остальное (адекватное автоматическое упорядочивание узлов на диаграмме, нормальные сплайны для рёбер и т.п.) должно допиливаться руками.

Спецификация инструмента для создания узлов


Наверное, вы обратили внимание на пустую палитру инструментов справа. Добавим туда инструмент для создания новых якорей. Для этого создайте новый раздел (New Tool -> Section) с идентификатором Nodes. Добавьте инструмент создания узла New Element Creation -> Node Creation с идентификатором CreateAnchor. В поле Label укажите Anchor. В поле Node Mappings добавьте Anchor. На вкладке Advanced можно добавить ссылку на иконку.

Разверните этот элемент, вы увидите определение двух переменных и блок Begin, который будет выполняться при использовании нашего инструмента. Добавьте в него операцию, задающую контекст (New Operation -> Change Context). В поле Browse Expression укажите var:container. Если вам (как и мне не понятно, что это за переменная), нажмите Ctrl + Space, и вы увидите, что она ссылается на объект типа anchor.Model, т.е. на корневой объект нашей модели.

В контексте корневого объекта модели нам нужно создать якорь (экземпляр метакласса anchor.Anchor). Для этого добавьте операцию создания экземпляра (New Operation -> Create Instance). В поле Reference Name укажите имя ассоциации текущего объекта (заданного через Change Context), с помощью которой нужно связать этот объект с создаваемым экземпляром. В данном случае это ассоциация anchors. В поле Type Name укажите anchor.Anchor. В поле Variable Name указывается имя переменной, которая будет ссылаться на созданный объект.

Сохраните спецификацию и попробуйте в редакторе диаграмм создать новый якорь. На вкладке свойств снизу укажите имя якоря.



Примечание

Вообще в Sirius доступно ещё множество разных операций, например, можно задавать имя нового якоря по умолчанию и т.п. Но с этим вы можете разобраться самостоятельно.

Спецификация инструмента для создания атрибутов


С атрибутами всё несколько сложнее, чем с якорями, потому что атрибуты не являются объектами верхнего уровня. Они принадлежат якорям, а не модели.

Скопируйте инструмент создания якорей, исправьте поля Id, Label и Node Mappings. Не забудьте, что это нужно проделать 4 раза (для каждого вида атрибутов). На вкладке Advanced в поле Extra Mappings добавьте Anchor. Это позволит создавать атрибуты не только в контексте модели, но и в контексте отдельных якорей.

Теперь нужно запретить создание атрибутов, не привязанных к якорю. Для этого на вкладке General в поле Precondition укажите ocl:container.oclIsKindOf(Anchor). Это значит, что в качестве контейнера для нового атрибута может использоваться только якорь.

У операции создания экземпляра (Create Instance) в поле Reference Name укажите attributes (это имя ассоциации между якорями и атрибутами). В Type Name укажите метакласс создаваемого атрибута.



Попробуйте создать новые атрибуты. Убедитесь, что при наведении указателя на пустую область на диаграмме появляется инструмент создания якоря. А при наведении на якорь – инструмент создания атрибута.

Спецификация других инструментов для создания, удаления и изменения объектов и связей


Инструменты для создания узлов и скреп делаются аналогично. Это достаточно муторно, но в GMF Tooling это ещё муторней, и гораздо муторней в GEF без использования каких-либо надстроек.

Инструменты для создания связей, я думаю, нет смысла описывать. Вы можете посмотреть примеры в проекте. Отмечу только, что для простых связей (якорь – атрибут или атрибут – узел) нужно использовать операцию Set. А для более сложных связей (скрепа – якорь, скрепа – узел) нужно создавать новые экземпляры объектов.

Также в проекте вы найдёте примеры инструментов удаления и изменения связей.

Спецификация фильтров


Диаграмма получается уже достаточно сложная, добавим фильтр, который будет скрывать лишние детали (атрибуты и узлы).

Для этого создайте в представлении Anchor Diagram составной фильтр (New Filter -> Composite Filter). Присвойте ему любой идентификатор и назовите Hide attributes and knots. Добавьте фильтр элементов диаграммы (New -> Mapping Filter). В поле Mappings укажите Knot, StaticAttribute, HistorizedAttribute, KnottedStaticAttribute, KnottedHistorizedAttribute.

После включения этого фильтра в редакторе диаграмм вы увидите что-то такое.



Спецификация правил валидации


В первой статье цикла вы видели примеры различных правил контроля. Правила, как и сама модель, были очень искусственными. Сейчас мы добавим в редактор диаграмм более полезное правило. Например, запретим одноимённые атрибуты у якоря.

Для этого добавьте в представление блок валидации (New Validation -> Validation).

Затем добавьте правило валидации элемента модели (New -> Semantic Validation Rule).

  • В поле Level укажите Error.
  • В поле Target Class укажите anchor.Anchor.
  • В поле Message укажите «The anchor has indistinguishable attributes».

Добавьте спецификацию правила (New -> Audit). В поле Audit Expression напишите

ocl:attributes->isUnique(name)

Попробуйте создать в модели два одноимённых атрибута у одного якоря и провалидировать модель (в контекстном меню диаграммы выберите Validate diagram). При этом у якоря появится иконка ошибки.

Сформулируем это правило несколько иначе. Создайте ещё одно правило:

  • В поле Level укажите Error.
  • В поле Target Class укажите anchor.Attribute.
  • В поле Message укажите «The attribute has non-unique name».

Добавьте спецификацию правила (New -> Audit). В поле Audit Expression напишите

ocl:anchor.attributes->excluding(self).name->excludes(self.name)

Теперь после валидации будет подсвечиваться не весь якорь, а отдельные атрибуты с неуникальными именами.



Заключение


После прочтения данной статьи вы должны понимать разницу между моделями и нотациями для моделей (например, диаграммами). Надеюсь, теперь вы умеете создавать языки моделирования и редакторы диаграмм для них.

Также вы увидели реальное применение OCL.

Если вам это интересно, то очень рекомендую создать какой-нибудь визуальный язык моделирования. Как вы можете убедиться, это такая же обыденная вещь как описание какого-нибудь класса или функции в коде.

В последующих статьях мы рассмотрим текстовые нотации для моделей. И конечно же займёмся самым главным – преобразованием моделей.

Комментарии (0)