Визуальное моделирование: теория и практика

Знакомство с DSM-платформой Microsoft DSL TOOLS

Разбить на страницы
Показывать лекцию целиком

Данная лекция предполагает, что вы готовы попробовать поработать с пакетом Microsoft DSL Tools самостоятельно. Для этого у вас должен быть некоторый опыт работы со средой разработки Microsoft Visual Studio, а также вы должны быть знакомы с языком C#. Впрочем, эта лекция может использоваться и для получения общего представления о том, что такое DSL Tools, но тогда вам придется смириться с тем, что часть материала будет непонятна.

Общие слова о том, как работать с пакетом

Пакет DSL Tools является одной из DSM-платформ и позволяет создавать собственные языки визуального моделирования, а также быстро, затрачивая небольшие усилия, реализовывать для них программный инструментарий - графический редактор с рядом дополнительных возможностей. Причем, набив руку, простые редакторы можно создавать прямо за несколько часов.

Этот пакет входит в состав Visual Studio 2005 SDK и может быть бесплатно взят с сайта компании Microsoft (http://www.microsoft.com/downloads). Он устанавливается в виде надстройки к Visual Studio и используется исключительно как составная часть этой среды разработки. После его инсталляции в Visual Studio появляется возможность создать специальный solution под названием Other Project Types\Domain-Specific Language Designer, и после его создания пакет DSL Tools становится доступным (в рамках данного solution).

В этом solution автоматически создаются два проекта - Dsl и DslPackage. Первый предназначен, главным образом, для хранения различных артефактов метамодели создаваемого DSL, второй хранит настройки пользовательского интерфейса целевого графического редактора. Оба могут содержать вставки на языке C#, с помощью которых базовая функциональность нового редактора может быть расширена.

Спецификация редактора подается на вход генератору DSL Tools, и по ней он создает уже обычный solution в Visual Studio. После его компиляции получается готовый редактор, который тут же, из Studio, можно запустить. Далее этот редактор появляется в списке инструментов, как отдельный Item, и его можно "прицепить" к вновь создаваемому в Visual Studio solution, в разработке которого желательно использовать этот новый редактор. Вне Visual Studio этот редактор использовать нельзя.

Метамодель, модель, сгенерированный код, откомпилированный код…

На практике, создавая графический редактор с использованием DSL Tools, особенно в начале, постоянно путаешься, где модель, а где метамодель, что генерируется, а что компилируется, где какие "исходники" и т. д. Чтобы прояснить общую картину и сделать ее более "операбельной", рассмотрим рис. 13.1, рис. 13.2, рис. 13.3, рис. 13.4, рис. 13.5.

(рис 13.1) Общая схема разработки графического редактора

На рис. 13.1 показано, что действия, связанные с разработкой и использованием нового редактора, делятся на три главных шага.

  • Создание метамодели нового DSL. Этот шаг подробно расписан на рис. 13.2.
  • Реализация по этой метамодели нового редактора. Этот шаг подробно расписан на рис. 13.3 и рис. 13.4.
  • Использование созданного редактора. Этот шаг подробно расписан на рис. 13.5.
  • Итак, создание метамодели нового языка происходит в два этапа. Первый - разработка концептуальной метамодели с помощью диаграмм классов UML. При этом определяются основные концепции языка, они обсуждаются с разными людьми, а также корректируются. Этот начально-публичный этап проекта по разработке нового редактора очень важен: нужно удачно "поймать" предметную область в сети нового формализма и не забыть важные детали. От этого во многом будет зависеть успех всего проекта. Возможность обсудить найденные абстракции с различными экспертами при этом крайне важна.

    (рис 13.2) Условное предложение в нотации языка VIPR

    Диаграммы классов UML для этих целей хорошо подходят, так как многим знакомы и не содержат деталей реализации, подобно диаграммам DSL Tools. Здесь можно использовать Microsoft Visio/UML Addon или любой другой UML-инструмент. Графический редактор DSL Tools не позволяет создавать компактные и удобные для обсуждения диаграммы: нет возможности задавать имена классов по-русски, все связи обозначаются специальными классами, что сильно увеличивает объем спецификации и т. д. На рис. 13.6, рис. 13.7, рис. 13.8 представлены спецификации языка SCL, выполненные в DSL Tools. Очевидно, что они более громоздки, чем метамодель с рис. 12.3.

    Далее, как следует из рис. 13.2, концептуальная метамодель переносится в DSL Tools. В итоге получается метамодель нового языка, выполненная уже в DSL Tools.

    (рис 13.3) Разработка редактора

    После этого, как показано на рис. 13.3, метамодель дополняется различными свойствами, определяющими особенности нашего редактора. Задается также пользовательский интерфейс - палитра с графическими символами, всплывающие меню для элементов на диаграммах нового редактора, диалоги свойств и пр. При этом используются настройки DSL Tools, а также может создаваться свой собственный код на C#.

    С помощью вставок на языке C# можно определить дополнительные свойства нового редактора в тех случаях, когда не хватает стандартных возможностей DSL Tools. Например, можно самостоятельно реализовать графический символ "ромб", который отсутствует в стандартной палитре DSL Tools, или задать возможность с помощью одной и той же связи соединять разные элементы нотации. Можно задать собственные правила валидации новых визуальных моделей, которые будут создаваться в новом редакторе. Архитектура DSL Tools устроена так, что в большинстве случаев новый код можно реализовать, аккуратно переопределив одни-два метода у автоматически генерируемых классов.

    В рамках DSL Tools можно, по специальным правилам, написать генерационный модуль, который будет выполнять генерацию произвольного текста по моделям, созданным в новом редакторе. Для этого нужно описать шаблон генерируемого файла: там, где нужно, вставить статический текст или, если выводимая информация зависит от свойств модели, сделать на языке C# вставку, которая извлекает нужную информацию из модели, надлежащим образом ее форматирует и выводит в это место файла.

    На рис. 13.4 показаны последующие действия, которые нужно выполнить после того, как определена метамодель нового языка и все дополнительные свойства нового редактора.

    (рис 13.4) Валидация, генерация, компиляция

    Итак, первый шаг - это валидация, что означает проверку на правильность и согласованность между собой всех элементов метамодели и их атрибутов. Такая поверка важна, поскольку если при компиляции возникнут ошибки, вызванные нашими нестыкующимися друг с другом действиями в DSL Tools, то понять, что произошло, в каком месте мы ошиблись, может оказаться непросто. Кроме того, часть ошибок может не "пойматься" при компиляции и "перекочевать" в откомпилированный код. Тогда наш целевой графический редактор будет работать неправильно или странно - и непонятно почему!

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

    На рис. 13.5.

    (рис 13.5) Использование нового редактора

    Разработка метамодели языка

    Рассмотрим детально процесс создания метамодели нового языка в DSL Tools. На рис. 13.6, рис. 13.7, рис. 13.8 представлена метамодель SCL-языка, который рассматривался в качестве примера в предыдущей лекции.

    (рис 13.6) Пример метамодели (часть I) (рис 13.7) Пример метамодели (часть II) (рис 13.8) Пример метамодели (часть III)

    Рисунки 13.6, 13.7, 13.8 представляют одну диаграмму в DSL-дизайнере, разрезанную на три части. Можно заметить, что эта диаграмма разделена на две горизонтальные области - Classes and Relations и Diagram Elements. Абстрактный синтаксис языка определяется в первой секции, а конкретный - во второй. Класс из первой секции соединяется линией-отношением с классом из второй секции, если определяет конструкцию, которая должна изображаться на диаграммах будущего графического редактора.

    Эта метамодель существенно отличается от той, которая была создана для языка SCL в предыдущей лекции. Во-первых, в прежней метамодели не было конкретного синтаксиса. Во-вторых, она была более абстрактной, так сказать, концептуальной, и не содержала многочисленной сопроводительной информации для автоматической генерации нового графического редактора (этой информации почти не видно на рис. 13.6, рис. 13.7, рис. 13.8, но она содержится в многочисленных свойствах классов метамодели). В-третьих, есть отличия в нотациях: в предыдущей лекции использовалось подмножество диаграмм классов UML 2.0, а в DSL-дизайнере реализована иная нотация.

    Теперь будут рассмотрены основные конструкции графического языка DSL дизайнера.

    Доменный класс (domain class) - используется для задания отдельной сущности нашего языка - например, состояния, списка сигналов и др. На рис. 13.6 можно увидеть доменные классы Root, Class, SignalList и т. д. Метамодель в DSL-дизайнере должна начинаться с корневого класса (в нашем случае это класс Root ). Все остальные классы располагаются в древообразной иерархии, соединяясь с предыдущим уровнем агрегированием, ассоциацией или наследованием.

    Ассоциация (domain relationship) соответствует обычной ассоциации между двумя классами в UML. Ассоциация, как и другие отношения между доменными классами, изображается на диаграмме специальным прямоугольником и является, по сути, тоже классом. Это сделано для того, чтобы можно было назначать различные свойства ассоциациям, в том числе определять доменные атрибуты для ассоциаций типа "многие-ко-многим".

    Агрегирование (embedding relationship) - используется для задания агрегирования одного доменного класса другим. Отличается от ассоциации фактически только тем, что при удалении объекта-агрегата по умолчанию удаляются объекты, соответствующие агрегируемому классу. На рис. 13.6, рис. 13.7, рис. 13.8 можно видеть много таких отношений, например, RootHasElement. Это отношение имеет множественность 1*:1..1 - каждый объект класса Element принадлежит строго одному объекту класса Root, а у одного объекта класса Root может быть много объектов класса Element.

    Наследование (inheritance) - соответствует обычному наследованию классов UML.

    Теперь поговорим об элементах, с помощью которых в DSL-дизайнере задается конкретный синтаксис языка. Они делятся на две группы - фигуры (shapes) и линии (connectors). Предлагаются следующие виды фигур.

    Геометрическая фигура (geometry shape) задает геометрическую фигуру одного из следующих видов: прямоугольник, прямоугольник со скругленными углами, эллипс, окружность. К сожалению, отсутствует ромб, хотя он часто встречается в различных графических нотациях.

    Сложная фигура (compatment shape) почти во всем аналогична геометрической фигуре, но позволяет задавать прямоугольники, у которых можно схлопывать/распахивать отдельные секции (например, секцию атрибутов и операций у прямоугольника, изображающего класс). На рис. 13.6, рис. 13.7, рис. 13.8 графические классы ClassShape и SignalListShape являются сложными фигурами.

    Произвольная картинка (image shape) - способ задать произвольное изображение (в виде, например, картинки в JPG- или BMP-формате) для конструкции DSL.

    Соединитель (connector) используется для задания линий в нотации нового DSL. На рис. 13.77 можно видеть соединитель TransitionConnector, который определяет способ изображения линий-переходов между состояниями.

    Несколько слов о том, как соединяются конструкции абстрактного и конкретного синтаксиса. Для этого в DSL-дизайнере предусмотрена специальная конструкция - диаграммный соединитель (diagram element map). На рис. 13.6, рис. 13.7, рис. 13.8 показано, что доменные классы и отношения (раздел диаграммы Classes and Relationships) соединены линиями с фигурами и соединителями (раздел диаграммы DSL-дизайнера под названием Diagram Elements). Эти линии и есть диаграммные соединители. При соединении доменных классов и отношений с фигурами и линиями у диаграммных соединителей автоматически "проставляется" соответствие между элементом абстрактного и конкретного синтаксиса. Далее нужно "вручную" задать соответствие между доменными свойствами и декораторами, а также задать некоторую дополнительную информацию.

    Для полноты картины далее перечислены остальные элементы нотации DSL-дизайнера:

  • именованный доменный класс (named domain class) - доменный класс, который имеет свойство "имя"; как показывает практика, большинство доменных классов имеют имена, поэтому этот класс полезен для удобства пользователей DSL -дизайнера;
  • разделитель (swimlane) - конструкция, которая позволяет задавать различные секции на диаграммах, как, например, секции Classes and Relationships и Diagram Elements на диаграммах DSL-дизайнера, а также задать, какие графические конструкции в какой секции будут располагаться на диаграммах будущего графического редактора;
  • порт (port shape) - специальный вид фигуры, позволяющий отображать доменный класс в виде круга/прямоугольника на границе фигуры (например, порты на диаграммах компонент в UML 2.0 ); на рис. 13.9 представлен фрагмент метамодели, определяющий порт, а на рис. 13.10 показана целевая диаграмма, созданная с помощью редактора, где были определены порты в соответствии с рис. 13.9.
  • (рис 13.9) Метамодель: определение порта (рис 13.10) Изображение порта в целевом редакторе, на диаграмме пользователя

    Все возможные конструкции, доступные в DSL-дизайнере, показаны на рис. 13.11, слева от рабочей области, в виде списка.

    (рис 13.11) Палитра DSL-дизайнера

    Обсудим теперь свойства элементов языка DSL-дизайнера. Для удобства использования они собраны в две основные группыНа самом деле групп несколько больше, да и свойства рассматриваемых здесь групп имеют больше атрибутов. Напомним, однако, что данная лекция не является переведенным на русский язык справочником по DSL Tools. Мы лишь объясняем основные концепции, а для практического использования DSL Tools читателю придется еще самостоятельно потрудиться.:

  • доменные свойства (Domain properties) - есть у всех классов;
  • декораторы (Decorators) - есть только у графических классов (фигур и соединителей).
  • Доменные свойства (Domain Propeties)

    Определяя в метамодели DSL Tools класс (доменный, отношение, графический класс), разработчик может создать у него произвольное количество доменных свойств. Для доменных классов такие свойства используются при задании свойств предметной области. Например, если у нас есть доменный класс "Тип Оборудования", то его атрибуты "маркировка", "изготовитель" и "описание" будут доменными свойствами. Для графических классов доменные свойства позволяют определить характеристики этих классов, связанные с метамоделью, в то время как декораторы определяют свойства таких классов, связанные с графическими характеристиками фигур.

    Каждое такое свойство имеет следующие группы атрибутов:

  • Code - характеристики данного свойства как свойства C# -класса; дело в том, что созданный в DSL-дизайнере класс будет превращен при генерации в C# -класс, а его свойства - в C# -свойства этого класса; группа атрибутов code определяет различные C# -характеристики данного свойства, например, его видимость ( public protected и т. д.);
  • Definition - определение таких характеристик доменного свойства, как его имя (Name), значение по умолчанию ( Default Value ), быть именем класса или нет ( Is Element Name ) - если да, тогда генератор обеспечит уникальность имен по умолчанию на диаграммах будущего графического редактора; еще один атрибут из этой группы - Kind, который может принимать значения normal или calculated ; в последнем случае у нас имеется вычисляемое свойство, которое задается некоторым кодом на языке C#, прилагаемом к метамодели;
  • Resources - дополнительные C#-характеристики свойства.
  • Рассмотрим пример calcutated-свойства. Одно такое свойство присутствует на рис. 13.8 - это свойство класса Transition под названием ComplexTransition. Оно задает текст на линии, обозначающей переход между двумя состояниями. Этот текст, во-первых, "собирается" из нескольких доменных классов и отношений, во-вторых, имеет сложное форматирование. Ниже представлен фрагмент кода на языке C#, который определяет правило вычисления и форматирования этого свойства:

    public partial class Transition
    {
     public string  GetComplexCaptionValue()
     {
      string result = string.Empty;
       result += string.Format(@"{0}/{1};{2}{3}",
         this.InvokedBy == null ? string.Empty : this.InvokedBy.Name,
          this.Signal == null ? string.Empty : this.Signal.Name,
           Environment.NewLine,
             this.Method == null? string.Empty : this.Method.Name);                    
       return result;
     }
    }

    Здесь используется механизм частичных классов языка C#, с помощью которого доопределяется класс Transition, автоматически генерируемый по классу Transition. Данный текст записывается в отдельный файл, который помещается в проекте Dsl.

    Декоратор (Decorator)

    Свойства такого типа могут встречаться у графических классов DSL-метамодели. У одного класса их может быть несколько, например, одно - для определения изображения имени фигуры на диаграмме, другое - для задания свойств текстовой секции фигуры (например, атрибут Collapse, который позволяет отображать такие секции на фигуре в двух режимах - в "схлопнутом" и развернутом виде). На рис. 13.7 у графического класса StateShape есть декоратор StateName, определяющий способ изображения имен состояний, которые будут создаваться в целевом графическом редакторе.

    Декораторы бывают следующих видов:

  • текст ( text );
  • изображение ( icon );
  • "схлопывающаяся" область ( Expand Collapse ).
  • Кроме того, свойства декоратора отличаются для фигуры и соединителя.

    Вот основные группы атрибутов декоратора:

  • Appearance - настройка шрифтов изображения;
  • Definition - имя в коде и в метамодели;
  • Layout - задание расположения текста;
  • Documentation - примечания метамодели;
  • Resources - настройка отображаемого текста.
  • Настройка палитры

    На рис. 13.11, слева, можно увидеть палитру ( toolbox ), в которой перечислены все конструкции нового языка, которые можно создавать на диаграммах. При активации элемента Edit/Toolbox в браузере вызывается инструмент для задания палитры: создаются ее элементы, которые связываются с соответствующими классами метамодели языка, задается иконка и другие свойства. Аналогичным образом настраивается и браузер целевого редактора.

    В итоге…

    На рис. 13.12 показан внешний вид целевого редактора, сгенерированный для языка SCL. Сравните это с рис. 13.7 предыдущей лекции.

    (рис 13.12) SCL-редактор

    Контрольные вопросы

  • Расскажите о тех задачах, для решения которых, по вашему мнению, предназначен пакет DSL Tools.
  • На вашем компьютере установлена Visual Studio. Опишите ваши действия по подготовке DSL Tools к работе. Проделайте эти действия.
  • На вашем компьютере пакет DSL Tools готов к работе. Опишите ваши начальные действия, вплоть до открытия рабочего окошка DSL Designer. Проделайте эти действия.
  • Почему целесообразно создавать метамодель нового DSL с помощью UML, вне DSL Tools, и только после ее завершения перенести ее DSL Tools?
  • Сформулируйте, для чего предназначены доменные классы DSL Tools.
  • Выскажите свое мнение о том, зачем в DSL Tools ассоциации изображаются с помощью специальных классов.
  • Опишите виды графических классов, используемых в DSL Tools для создания метамодели нового языка.
  • Как в метамоделях DSL Tools реализуется связь доменных графических классов?
  • Для задания какой информации используется доменное свойство?
  • Для задания какой информации используется декоратор?
  • Приведите пример вставки собственного кода в проект нового редактора, разрабатываемого с помощью DSL Tools. Попробуйте написать, вставить и протестировать (в составе итогового редактора) собственный "ручной" код.
  • Зачем в DSL Tools используется валидация?
  • Попробуйте оценить (отдавая отчет в недостаточности имеющейся у вас информации!) эффективность использования DSL Tools в промышленном проекте. Постарайтесь определить минимальный нижний порог сочетания "объем проекта/компетентность специалистов" для того, чтобы пакет DSL Tools "выстрелил".
  • Вам предложили реализовать в DSL Tools язык UML. Возможно ли будет это сделать? Что облегчит, а что затруднит вашу работу?
  • Страницы:

    Данная лекция предполагает, что вы готовы попробовать поработать с пакетом Microsoft DSL Tools самостоятельно. Для этого у вас должен быть некоторый опыт работы со средой разработки Microsoft Visual Studio, а также вы должны быть знакомы с языком C#. Впрочем, эта лекция может использоваться и для получения общего представления о том, что такое DSL Tools, но тогда вам придется смириться с тем, что часть материала будет непонятна.

    Общие слова о том, как работать с пакетом

    Пакет DSL Tools является одной из DSM-платформ и позволяет создавать собственные языки визуального моделирования, а также быстро, затрачивая небольшие усилия, реализовывать для них программный инструментарий - графический редактор с рядом дополнительных возможностей. Причем, набив руку, простые редакторы можно создавать прямо за несколько часов.

    Этот пакет входит в состав Visual Studio 2005 SDK и может быть бесплатно взят с сайта компании Microsoft (http://www.microsoft.com/downloads). Он устанавливается в виде надстройки к Visual Studio и используется исключительно как составная часть этой среды разработки. После его инсталляции в Visual Studio появляется возможность создать специальный solution под названием Other Project Types\Domain-Specific Language Designer, и после его создания пакет DSL Tools становится доступным (в рамках данного solution).

    В этом solution автоматически создаются два проекта - Dsl и DslPackage. Первый предназначен, главным образом, для хранения различных артефактов метамодели создаваемого DSL, второй хранит настройки пользовательского интерфейса целевого графического редактора. Оба могут содержать вставки на языке C#, с помощью которых базовая функциональность нового редактора может быть расширена.

    Спецификация редактора подается на вход генератору DSL Tools, и по ней он создает уже обычный solution в Visual Studio. После его компиляции получается готовый редактор, который тут же, из Studio, можно запустить. Далее этот редактор появляется в списке инструментов, как отдельный Item, и его можно "прицепить" к вновь создаваемому в Visual Studio solution, в разработке которого желательно использовать этот новый редактор. Вне Visual Studio этот редактор использовать нельзя.

    Метамодель, модель, сгенерированный код, откомпилированный код…

    На практике, создавая графический редактор с использованием DSL Tools, особенно в начале, постоянно путаешься, где модель, а где метамодель, что генерируется, а что компилируется, где какие "исходники" и т. д. Чтобы прояснить общую картину и сделать ее более "операбельной", рассмотрим рис. 13.1, рис. 13.2, рис. 13.3, рис. 13.4, рис. 13.5.

    (рис 13.1) Общая схема разработки графического редактора

    На рис. 13.1 показано, что действия, связанные с разработкой и использованием нового редактора, делятся на три главных шага.

  • Создание метамодели нового DSL. Этот шаг подробно расписан на рис. 13.2.
  • Реализация по этой метамодели нового редактора. Этот шаг подробно расписан на рис. 13.3 и рис. 13.4.
  • Использование созданного редактора. Этот шаг подробно расписан на рис. 13.5.
  • Итак, создание метамодели нового языка происходит в два этапа. Первый - разработка концептуальной метамодели с помощью диаграмм классов UML. При этом определяются основные концепции языка, они обсуждаются с разными людьми, а также корректируются. Этот начально-публичный этап проекта по разработке нового редактора очень важен: нужно удачно "поймать" предметную область в сети нового формализма и не забыть важные детали. От этого во многом будет зависеть успех всего проекта. Возможность обсудить найденные абстракции с различными экспертами при этом крайне важна.

    (рис 13.2) Условное предложение в нотации языка VIPR

    Диаграммы классов UML для этих целей хорошо подходят, так как многим знакомы и не содержат деталей реализации, подобно диаграммам DSL Tools. Здесь можно использовать Microsoft Visio/UML Addon или любой другой UML-инструмент. Графический редактор DSL Tools не позволяет создавать компактные и удобные для обсуждения диаграммы: нет возможности задавать имена классов по-русски, все связи обозначаются специальными классами, что сильно увеличивает объем спецификации и т. д. На рис. 13.6, рис. 13.7, рис. 13.8 представлены спецификации языка SCL, выполненные в DSL Tools. Очевидно, что они более громоздки, чем метамодель с рис. 12.3.

    Далее, как следует из рис. 13.2, концептуальная метамодель переносится в DSL Tools. В итоге получается метамодель нового языка, выполненная уже в DSL Tools.

    (рис 13.3) Разработка редактора

    После этого, как показано на рис. 13.3, метамодель дополняется различными свойствами, определяющими особенности нашего редактора. Задается также пользовательский интерфейс - палитра с графическими символами, всплывающие меню для элементов на диаграммах нового редактора, диалоги свойств и пр. При этом используются настройки DSL Tools, а также может создаваться свой собственный код на C#.

    С помощью вставок на языке C# можно определить дополнительные свойства нового редактора в тех случаях, когда не хватает стандартных возможностей DSL Tools. Например, можно самостоятельно реализовать графический символ "ромб", который отсутствует в стандартной палитре DSL Tools, или задать возможность с помощью одной и той же связи соединять разные элементы нотации. Можно задать собственные правила валидации новых визуальных моделей, которые будут создаваться в новом редакторе. Архитектура DSL Tools устроена так, что в большинстве случаев новый код можно реализовать, аккуратно переопределив одни-два метода у автоматически генерируемых классов.

    В рамках DSL Tools можно, по специальным правилам, написать генерационный модуль, который будет выполнять генерацию произвольного текста по моделям, созданным в новом редакторе. Для этого нужно описать шаблон генерируемого файла: там, где нужно, вставить статический текст или, если выводимая информация зависит от свойств модели, сделать на языке C# вставку, которая извлекает нужную информацию из модели, надлежащим образом ее форматирует и выводит в это место файла.

    На рис. 13.4 показаны последующие действия, которые нужно выполнить после того, как определена метамодель нового языка и все дополнительные свойства нового редактора.

    (рис 13.4) Валидация, генерация, компиляция

    Итак, первый шаг - это валидация, что означает проверку на правильность и согласованность между собой всех элементов метамодели и их атрибутов. Такая поверка важна, поскольку если при компиляции возникнут ошибки, вызванные нашими нестыкующимися друг с другом действиями в DSL Tools, то понять, что произошло, в каком месте мы ошиблись, может оказаться непросто. Кроме того, часть ошибок может не "пойматься" при компиляции и "перекочевать" в откомпилированный код. Тогда наш целевой графический редактор будет работать неправильно или странно - и непонятно почему!

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

    На рис. 13.5.

    (рис 13.5) Использование нового редактора

    Разработка метамодели языка

    Рассмотрим детально процесс создания метамодели нового языка в DSL Tools. На рис. 13.6, рис. 13.7, рис. 13.8 представлена метамодель SCL-языка, который рассматривался в качестве примера в предыдущей лекции.

    (рис 13.6) Пример метамодели (часть I) (рис 13.7) Пример метамодели (часть II) (рис 13.8) Пример метамодели (часть III)

    Рисунки 13.6, 13.7, 13.8 представляют одну диаграмму в DSL-дизайнере, разрезанную на три части. Можно заметить, что эта диаграмма разделена на две горизонтальные области - Classes and Relations и Diagram Elements. Абстрактный синтаксис языка определяется в первой секции, а конкретный - во второй. Класс из первой секции соединяется линией-отношением с классом из второй секции, если определяет конструкцию, которая должна изображаться на диаграммах будущего графического редактора.

    Эта метамодель существенно отличается от той, которая была создана для языка SCL в предыдущей лекции. Во-первых, в прежней метамодели не было конкретного синтаксиса. Во-вторых, она была более абстрактной, так сказать, концептуальной, и не содержала многочисленной сопроводительной информации для автоматической генерации нового графического редактора (этой информации почти не видно на рис. 13.6, рис. 13.7, рис. 13.8, но она содержится в многочисленных свойствах классов метамодели). В-третьих, есть отличия в нотациях: в предыдущей лекции использовалось подмножество диаграмм классов UML 2.0, а в DSL-дизайнере реализована иная нотация.

    Теперь будут рассмотрены основные конструкции графического языка DSL дизайнера.

    Доменный класс (domain class) - используется для задания отдельной сущности нашего языка - например, состояния, списка сигналов и др. На рис. 13.6 можно увидеть доменные классы Root, Class, SignalList и т. д. Метамодель в DSL-дизайнере должна начинаться с корневого класса (в нашем случае это класс Root ). Все остальные классы располагаются в древообразной иерархии, соединяясь с предыдущим уровнем агрегированием, ассоциацией или наследованием.

    Ассоциация (domain relationship) соответствует обычной ассоциации между двумя классами в UML. Ассоциация, как и другие отношения между доменными классами, изображается на диаграмме специальным прямоугольником и является, по сути, тоже классом. Это сделано для того, чтобы можно было назначать различные свойства ассоциациям, в том числе определять доменные атрибуты для ассоциаций типа "многие-ко-многим".

    Агрегирование (embedding relationship) - используется для задания агрегирования одного доменного класса другим. Отличается от ассоциации фактически только тем, что при удалении объекта-агрегата по умолчанию удаляются объекты, соответствующие агрегируемому классу. На рис. 13.6, рис. 13.7, рис. 13.8 можно видеть много таких отношений, например, RootHasElement. Это отношение имеет множественность 1*:1..1 - каждый объект класса Element принадлежит строго одному объекту класса Root, а у одного объекта класса Root может быть много объектов класса Element.

    Наследование (inheritance) - соответствует обычному наследованию классов UML.

    Теперь поговорим об элементах, с помощью которых в DSL-дизайнере задается конкретный синтаксис языка. Они делятся на две группы - фигуры (shapes) и линии (connectors). Предлагаются следующие виды фигур.

    Геометрическая фигура (geometry shape) задает геометрическую фигуру одного из следующих видов: прямоугольник, прямоугольник со скругленными углами, эллипс, окружность. К сожалению, отсутствует ромб, хотя он часто встречается в различных графических нотациях.

    Сложная фигура (compatment shape) почти во всем аналогична геометрической фигуре, но позволяет задавать прямоугольники, у которых можно схлопывать/распахивать отдельные секции (например, секцию атрибутов и операций у прямоугольника, изображающего класс). На рис. 13.6, рис. 13.7, рис. 13.8 графические классы ClassShape и SignalListShape являются сложными фигурами.

    Произвольная картинка (image shape) - способ задать произвольное изображение (в виде, например, картинки в JPG- или BMP-формате) для конструкции DSL.

    Соединитель (connector) используется для задания линий в нотации нового DSL. На рис. 13.77 можно видеть соединитель TransitionConnector, который определяет способ изображения линий-переходов между состояниями.

    Несколько слов о том, как соединяются конструкции абстрактного и конкретного синтаксиса. Для этого в DSL-дизайнере предусмотрена специальная конструкция - диаграммный соединитель (diagram element map). На рис. 13.6, рис. 13.7, рис. 13.8 показано, что доменные классы и отношения (раздел диаграммы Classes and Relationships) соединены линиями с фигурами и соединителями (раздел диаграммы DSL-дизайнера под названием Diagram Elements). Эти линии и есть диаграммные соединители. При соединении доменных классов и отношений с фигурами и линиями у диаграммных соединителей автоматически "проставляется" соответствие между элементом абстрактного и конкретного синтаксиса. Далее нужно "вручную" задать соответствие между доменными свойствами и декораторами, а также задать некоторую дополнительную информацию.

    Для полноты картины далее перечислены остальные элементы нотации DSL-дизайнера:

  • именованный доменный класс (named domain class) - доменный класс, который имеет свойство "имя"; как показывает практика, большинство доменных классов имеют имена, поэтому этот класс полезен для удобства пользователей DSL -дизайнера;
  • разделитель (swimlane) - конструкция, которая позволяет задавать различные секции на диаграммах, как, например, секции Classes and Relationships и Diagram Elements на диаграммах DSL-дизайнера, а также задать, какие графические конструкции в какой секции будут располагаться на диаграммах будущего графического редактора;
  • порт (port shape) - специальный вид фигуры, позволяющий отображать доменный класс в виде круга/прямоугольника на границе фигуры (например, порты на диаграммах компонент в UML 2.0 ); на рис. 13.9 представлен фрагмент метамодели, определяющий порт, а на рис. 13.10 показана целевая диаграмма, созданная с помощью редактора, где были определены порты в соответствии с рис. 13.9.
  • (рис 13.9) Метамодель: определение порта (рис 13.10) Изображение порта в целевом редакторе, на диаграмме пользователя

    Все возможные конструкции, доступные в DSL-дизайнере, показаны на рис. 13.11, слева от рабочей области, в виде списка.

    (рис 13.11) Палитра DSL-дизайнера

    Обсудим теперь свойства элементов языка DSL-дизайнера. Для удобства использования они собраны в две основные группыНа самом деле групп несколько больше, да и свойства рассматриваемых здесь групп имеют больше атрибутов. Напомним, однако, что данная лекция не является переведенным на русский язык справочником по DSL Tools. Мы лишь объясняем основные концепции, а для практического использования DSL Tools читателю придется еще самостоятельно потрудиться.:

  • доменные свойства (Domain properties) - есть у всех классов;
  • декораторы (Decorators) - есть только у графических классов (фигур и соединителей).
  • Доменные свойства (Domain Propeties)

    Определяя в метамодели DSL Tools класс (доменный, отношение, графический класс), разработчик может создать у него произвольное количество доменных свойств. Для доменных классов такие свойства используются при задании свойств предметной области. Например, если у нас есть доменный класс "Тип Оборудования", то его атрибуты "маркировка", "изготовитель" и "описание" будут доменными свойствами. Для графических классов доменные свойства позволяют определить характеристики этих классов, связанные с метамоделью, в то время как декораторы определяют свойства таких классов, связанные с графическими характеристиками фигур.

    Каждое такое свойство имеет следующие группы атрибутов:

  • Code - характеристики данного свойства как свойства C# -класса; дело в том, что созданный в DSL-дизайнере класс будет превращен при генерации в C# -класс, а его свойства - в C# -свойства этого класса; группа атрибутов code определяет различные C# -характеристики данного свойства, например, его видимость ( public protected и т. д.);
  • Definition - определение таких характеристик доменного свойства, как его имя (Name), значение по умолчанию ( Default Value ), быть именем класса или нет ( Is Element Name ) - если да, тогда генератор обеспечит уникальность имен по умолчанию на диаграммах будущего графического редактора; еще один атрибут из этой группы - Kind, который может принимать значения normal или calculated ; в последнем случае у нас имеется вычисляемое свойство, которое задается некоторым кодом на языке C#, прилагаемом к метамодели;
  • Resources - дополнительные C#-характеристики свойства.
  • Рассмотрим пример calcutated-свойства. Одно такое свойство присутствует на рис. 13.8 - это свойство класса Transition под названием ComplexTransition. Оно задает текст на линии, обозначающей переход между двумя состояниями. Этот текст, во-первых, "собирается" из нескольких доменных классов и отношений, во-вторых, имеет сложное форматирование. Ниже представлен фрагмент кода на языке C#, который определяет правило вычисления и форматирования этого свойства:

    public partial class Transition
    {
     public string  GetComplexCaptionValue()
     {
      string result = string.Empty;
       result += string.Format(@"{0}/{1};{2}{3}",
         this.InvokedBy == null ? string.Empty : this.InvokedBy.Name,
          this.Signal == null ? string.Empty : this.Signal.Name,
           Environment.NewLine,
             this.Method == null? string.Empty : this.Method.Name);                    
       return result;
     }
    }

    Здесь используется механизм частичных классов языка C#, с помощью которого доопределяется класс Transition, автоматически генерируемый по классу Transition. Данный текст записывается в отдельный файл, который помещается в проекте Dsl.

    Декоратор (Decorator)

    Свойства такого типа могут встречаться у графических классов DSL-метамодели. У одного класса их может быть несколько, например, одно - для определения изображения имени фигуры на диаграмме, другое - для задания свойств текстовой секции фигуры (например, атрибут Collapse, который позволяет отображать такие секции на фигуре в двух режимах - в "схлопнутом" и развернутом виде). На рис. 13.7 у графического класса StateShape есть декоратор StateName, определяющий способ изображения имен состояний, которые будут создаваться в целевом графическом редакторе.

    Декораторы бывают следующих видов:

  • текст ( text );
  • изображение ( icon );
  • "схлопывающаяся" область ( Expand Collapse ).
  • Кроме того, свойства декоратора отличаются для фигуры и соединителя.

    Вот основные группы атрибутов декоратора:

  • Appearance - настройка шрифтов изображения;
  • Definition - имя в коде и в метамодели;
  • Layout - задание расположения текста;
  • Documentation - примечания метамодели;
  • Resources - настройка отображаемого текста.
  • Настройка палитры

    На рис. 13.11, слева, можно увидеть палитру ( toolbox ), в которой перечислены все конструкции нового языка, которые можно создавать на диаграммах. При активации элемента Edit/Toolbox в браузере вызывается инструмент для задания палитры: создаются ее элементы, которые связываются с соответствующими классами метамодели языка, задается иконка и другие свойства. Аналогичным образом настраивается и браузер целевого редактора.

    В итоге…

    На рис. 13.12 показан внешний вид целевого редактора, сгенерированный для языка SCL. Сравните это с рис. 13.7 предыдущей лекции.

    (рис 13.12) SCL-редактор

    Контрольные вопросы

  • Расскажите о тех задачах, для решения которых, по вашему мнению, предназначен пакет DSL Tools.
  • На вашем компьютере установлена Visual Studio. Опишите ваши действия по подготовке DSL Tools к работе. Проделайте эти действия.
  • На вашем компьютере пакет DSL Tools готов к работе. Опишите ваши начальные действия, вплоть до открытия рабочего окошка DSL Designer. Проделайте эти действия.
  • Почему целесообразно создавать метамодель нового DSL с помощью UML, вне DSL Tools, и только после ее завершения перенести ее DSL Tools?
  • Сформулируйте, для чего предназначены доменные классы DSL Tools.
  • Выскажите свое мнение о том, зачем в DSL Tools ассоциации изображаются с помощью специальных классов.
  • Опишите виды графических классов, используемых в DSL Tools для создания метамодели нового языка.
  • Как в метамоделях DSL Tools реализуется связь доменных графических классов?
  • Для задания какой информации используется доменное свойство?
  • Для задания какой информации используется декоратор?
  • Приведите пример вставки собственного кода в проект нового редактора, разрабатываемого с помощью DSL Tools. Попробуйте написать, вставить и протестировать (в составе итогового редактора) собственный "ручной" код.
  • Зачем в DSL Tools используется валидация?
  • Попробуйте оценить (отдавая отчет в недостаточности имеющейся у вас информации!) эффективность использования DSL Tools в промышленном проекте. Постарайтесь определить минимальный нижний порог сочетания "объем проекта/компетентность специалистов" для того, чтобы пакет DSL Tools "выстрелил".
  • Вам предложили реализовать в DSL Tools язык UML. Возможно ли будет это сделать? Что облегчит, а что затруднит вашу работу?
  • Вернуться к учебному плану