Перейти к тексту

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

При первом входе в developerWorks для Вас будет создан профиль. Выберите информацию отображаемую в Вашем профиле — скрыть или отобразить поля можно в любой момент.

Вся введенная информация защищена.

  • Закрыть [x]

При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

Вся введенная информация защищена.

  • Закрыть [x]

Советы по использованию преобразований UML - C++ в Rational Systems Developer и Rational Software Architect

Контроль кода С++, генерируемого из UML-модели

Сандип Кохли, старший инженер-программист, IBM
Сандип Кохли (Sandeep Kohli) - ведущий разработчик и архитектор в рабочей группе Rational Software Architect / Rational Systems Developer в г. Бангалор. Он работал с различными инструментами моделирования Rational, включая Rational Rose, Rational RoseRT и Rational Software Architect и, кроме того, с компиляторами C/C++/Fortran/Ada.
Шрирупа Сен, старший инженер-программист, IBM
Шрирупа Сен (Sreerupa Sen) работает в IBM в качестве разработчика архитектуры и имеет дело с инструментами UML-моделирования Rational. На протяжении своей карьеры в сфере разработки программного обеспечения ей приходилось работать в различных областях, в том числе она занималась банковскими приложениями, связующим ПО, центрами вспомогательных данных и инструментами моделирования. В IBM она занималась продуктами Rational Software Architect/Rational Systems Developer, особенно связанными с языком C++.

Описание:  UML - это язык общего назначения. IBM® Rational® Software Architect и IBM® Rational® Systems Developer позволяют расширить функциональность UML-моделирования за счет поддержки конструкций, специфических для языка программирования C++. Преобразования UML - C++ в Rational Software Architect и Rational Systems Developer конвертируют UML-модели в код на языке C++. В этой статье рассматриваются различные советы по поводу того, как добиться более детализированного контроля над кодом C++, генерируемым при запуске преобразования UML - C++. Статья делится на несколько разделов, в каждом разделе рассматривается одна из методик. Вы можете просматривать эти разделы в любом порядке.

Дата:  18.12.2007
Уровень сложности:  средний
Активность:  985 просмотров
Комментарии:  


Применение профиля преобразования C++ к моделированию конструкций C++

Обычно для того, чтобы перекинуть мост между унифицированным языком моделирования (Unified Modeling Language, UML) и конкретной предметной областью, используют профили UML. Профиль UML позволяет определить дополнительные семантические правила и характеристики для существующих UML -элементов - классов, операций и т. п.. Для моделирования элементов, специфичных для C++, то есть структур, объединений, пространств имен (и т. д.), необходимо использовать профиль UML Модуль преобразования UML - C++ в Rational Software Architect и Rational Systems Developer поставляется в комплекте с профилем преобразования C++. Этот профиль можно применить к UML-модели следующим образом.

  1. Выберите в обозревателе проектов Project Explorer UML-модель, к которой нужно применить профиль;
  2. Не снимая выделения с модели в Project Explorer, переключитесь на представление Properties и перейдите на вкладку Profiles;
  3. Нажмите кнопку Add Profile, как показано на рисунке 1;

Рисунок 1. Применение профиля преобразования UML - C++
Применение профиля преобразования  UML - C++
  1. Выберите пункт C++ Transformation из раскрывающегося списка Deployed Profile, показанного на рисунке 2.

Рисунок 2. Выбор Преобразования C++
Пример модели  UML2

Импорт библиотеки типов C++

UML предоставляет ограниченный набор встроенных типов. Это такие типы, как Boolean, Integer, String и UnlimitedNatural. Большинство языков программирования, в том числе C++, предлагают гораздо более богатый набор примитивов. Если вы моделируете для C++, вам часто будут нужны встроенные элементарные типы, специфичные для C++ (например, при присваивании типа атрибуту, параметру, типу возврата операции и т. д.). Чтобы импортировать библиотеку моделей C++, поставляемую с модулем преобразования C++ Transform, нажмите правой кнопкой мыши на UML-модели в Project Explorer и выберите команду Import Model Library, как показано на рисунке 3.


Рисунок 3. Импорт библиотеки типов C++
Импорт библиотеки типов C++с помощью контекстного меню

Выделите пункт C++ Types в списке Deployed Library, как показано на рисунке 4.


Рисунок 4. Импорт библиотеки типов C++
Импорт библиотеки типов C++

Создание пространств имен C++ в модели

В этом разделе рассказывается о том, как моделировать пространства имен C++ в UML-модели. Чтобы создать пространство имен в C++, необходимо применить стереотип cpp_namespace к UML-пакету. По умолчанию, преобразование UML - C++ отображает UML-пакет в папку. Чтобы отобразить UML-пакет не в папку, а в пространство имен, необходимо применить к нему стереотип cpp_namespace, а затем присвоить свойству NamespaceName, ассоциируемому с этим стереотипом, значение - имя пространства имен. Все классы, структуры, перечисления (и т. п.) стереотипного UML-пакета в формируемом коде будут сгенерированы в этом пространстве имен.

Вам может быть интересно, почему это пространство имен не получает имя стереотипного пакета. Причина - поддержка моделирования анонимных пространств имен в C++. То есть, если вы оставите свойство NamespaceName незаполненным, то пространство имен будет считаться анонимным.


Моделирование определяемых типов C++

Чтобы смоделировать определяемый тип C++(typedef), создайте UML-класс и примените к нему стереотип cpp_typdef. Этот стереотип предлагает три пары свойство/значение:

  • arrayDimensions
  • ImplementationType
  • qualifier

Чтобы создать определяемый тип typedef int const IntMatrix100_20_t [10][20];, создайте UML-класс IntMatrix100_20_t и примените к нему стереотип cpp_typedef. Задайте для этого стереотипа свойства в соответствии с рисунком 5.


Рисунок 5. Создание определяемого типа C++
Свойства определяемого типа C++

Чтобы понять зависимость определения определяемого типа от свойств, предоставляемых профилем, вы можете представить себе определяемый тип следующим образом: typedef <ImplementationType> <qualifier> <Class Name> <arrayDimensions>


Создание атрибутов многомерных массивов

В этом разделе рассказывается о том, как создать атрибут-трехмерный массив размерностью [10][20][30]. Выберите в обозревателе проектов Project Explorer атрибут, который нужно реализовать в виде многомерного массива. В представлении Properties перейдите на вкладку Stereotypes. На вкладке Stereotypes нажмите кнопку Apply Stereotypes и выберите стереотип cpp_type. Этот стереотип предлагает следующие пары свойство/значение:

  • arrayDimensions
  • InitializerKind
  • isAuto
  • isMutable
  • isRegister
  • isVolatile
  • qualifier

В поле arrayDimensions Value, изображенном на рисунке 6, укажите [10][20][30]. В результате этого в исходном коде будет сгенерирован атрибут с размерами массива [10][20][30].


Рисунок 6. Настройка многомерных атрибутов
Настройка многомерных атрибутов

Определение формального параметра метода как константного

Этот прием использует те же принципы, что и предыдущий (определение многомерного массива). Выделите в Project Explorer параметр, который должен быть константным. В представлении Properties перейдите на вкладку Stereotypes. На вкладке Stereotypes нажмите кнопку Apply Stereotypes и выберите стереотип cpp_type. Этот стереотип предоставляет следующие пары свойство/значение:

  • arrayDimensions
  • InitializerKind
  • isAuto
  • isMutable
  • isRegister
  • isVolatile
  • qualifier

Все эти свойства могут быть полезными, но сейчас нас интересует только свойство qualifier. В поле Value для свойства qualifier введите значение const (как показано на Рисунке 5). Благодаря этому после выполнения преобразования в исходном коде будет сгенерирована сигнатура функции с константным спецификатором для выбранного параметра.

Примечание: убедитесь, что значение, которое вы указываете в этом поле, является корректным. Некорректное значение вызовет ошибку компиляции, которую придется исправлять до выполнения преобразования UML - C++.

Обратите внимание на то, что стереотип cpp_type применим также к атрибутам и классам. Однако для того, чтобы сгенерировать константный атрибут, проще просто пометить его как Read Only.


Как сделать константным весь метод

Предположим, что вы хотите объявить метод константным, чтобы он был сгенерирован с константным ключевым словом, как в )int Operation1(MyType Parameter1 const;. Для этого необходимо установить флажок для спецификатора Query на вкладке General в представлении Properties для этого метода, как показано на рисунке 7. Чтобы воспользоваться этой возможностью, нет необходимости в применении стереотипа.


Рисунок 7. Создание константного метода
Константный  метод C++

Добавление исключения в метод

Исключения - это приоритетные элементы в UML, поэтому их можно моделировать без использования профилей. Для упрощения и обобщения практики моделирования преобразования UML - C++ везде, где это возможно, используют свойства UML, а не профили. Чтобы сгенерировать предложение throw для функции, например, int Operation1() throw ( MyType);, необходимо сначала создать параметр для этой операции и установить для свойства Is Exception значение true.

Имя параметра не имеет значения, поскольку оно игнорируется в процессе преобразования, но лучше выбрать такое имя, которое позволит правильно идентифицировать исключение при его возникновении. На рисунке 8 показано, как установить для параметра Is Exception значение true.


Рисунок 8. Установление типа вызова исключительной ситуации для метода
Предложение Throw для метода

Контроль над предложениями include в генерируемом коде

Преобразование UML - C++ предназначено для автоматического выделения отношений из модели с последующим генерированием корректных предложений include или объявлений forward. Однако могут возникнуть ситуации, в которых вы захотите контролировать формирование предложений include. Например, вы хотите использовать в теле метода локальные переменные определенного типа, и поэтому вам нужно, чтобы в файле тела были сгенерированы предложения include для этого типа.

Вам придется явным образом смоделировать такие случаи, создав UML-отношение между этими двумя классами и применив к этому отношению стереотип cpp_dependency. Этот стереотип поставляется со свойством IsInclusionInHeader, значение которого по умолчанию равно false. Если вы хотите, чтобы предложения include были сгенерированы в файле тела, то вы должны оставить значение по умолчанию (false). Если эти предложения include нужно сгенерировать в заголовке, то следует либо вообще не применять стереотип cpp_dependency к созданному отношению, либо применить стереотип и установить для свойства IsInclusionInHeader значение true.


Использование секций сохранения кода при воспроизведении преобразования на уровне файла

Если вам нужно использовать в исходном коде типы из стандартной библиотеки или из какой-либо другой библиотеки, то в модели такие строки необходимо определить как простые строки (plain string). Например, если нужно объявить атрибут как vector of integers, в модели вы определили бы его тип как vector<int>. В процессе преобразования этот тип будет считаться примитивным типом, в результате чего для него не будут сгенерированы предложения include или объявления forward. Следовательно, такие типы необходимо включить в исходные файлы явным образом.

Например, для типа vector необходимо вставить в исходный код явное предложение include для типа vector: #include <vector>. Для поддержки этой возможности в каждом сгенерированном файле предусмотрена секция, которая будет сохранена дословно при повторном применении преобразования UML-C++, как показано в следующем листинге (см. листинг 1). Обратите внимание на строку //TODO: Add definitions that you want preserved (Добавьте определения, которые должны быть сохранены). Все, что вы напишете между комментариями Начало секции и Завершение секции, будет сохранено. Именно сюда можно добавлять такие предложения, как #include <vector>.


Листинг 1. Код, сгенерированный для класса Car
                

#ifndef CLASS1_H
#define CLASS1_H
//Начало секции для файла Class1.h
//TODO: Добавьте определения, которые должны быть сохранены
//Завершение секции для файла Class1.h

#include "MyType.h"

//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
class Class1
{

     //Начало секции для Class1
    //TODO: Добавьте определения, которые должны быть сохранены
    //Конец секции для Class1
    public:

        //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
        int Operation1()const  throw ( MyType);

};  //Завершение описания класса Class1

#endif
	      


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

Обратите внимание на то, что в коде предыдущего листинга имеется строка //Начало секции для Class1 ... //Завершение секции для Class1 . Вы можете поместить здесь все специфические предложения языка C++, которые вы не можете смоделировать, и они будут сохраняться до тех пор, пока вы явным образом их не удалите. При повторном применении преобразования UML - C++ предложения в этой секции не будут перезаписаны. Если вам не нужна эта секция в генерируемом коде, то, возможно, вы захотите удалить ее. При повторном выполнении преобразования UML - C++ она не будет сгенерирована снова. Именно так вы сможете избавиться от комментариев, которые вам не нужны.

В этом случае удалите следующую секцию (см. листинг 2), после чего она не будет восстановлена автоматически. Если вам снова понадобится эта секция, то придется вставить ее вручную в этом же месте кода.


Листинг 2. Код, сгенерированный для класса Car
                
    ...
    //Начало секции для Class1
    //TODO: Добавьте определения, которые должны быть сохранены
    //Завершение секции для Class1
    ...     


Как изменить имя генерируемого пакета, не изменяя UML-модель

Чтобы изменить имя пакета, выполните двойной щелчок на конфигурационном файле преобразования, чтобы открыть его в редакторе. Перейдите на вкладку Mapping и установите флажок Enable mapping, как показано на рисунке 9.


Рисунок 9. Разрешение отображения модели
Разрешение отображения модели

Нажмите кнопку New, чтобы создать модель отображения по умолчанию и дать ей подходящее имя. Нажмите кнопку Edit Mapping, чтобы вывести на экран диалоговое окно, показанное на рисунке 10.


Рисунок 10. Редактирование модели отображения
Редактирование модели отображения

Предположим, вы работаете с UML-моделью, показанной на рисунке 11. Если у вас нет модели отображения, то класс Date будет сгенерирован в папке с именем Package1. Если же вы хотите, чтобы Package1 был сгенерирован как Folder1, тогда вам нужно будет использовать модель отображения. Для этого в модели отображения перейдите к элементу Package1, а затем в редактируемом поле Mapped Name в нижней части страницы мастера введите имя Folder1. Теперь в генерируемом коде класс Date будет помещен в папку с именем Folder1.


Рисунок 11. Рабочая UML-модель
Отображение UML-модели

Как сгенерировать несколько классов в одном файле

Когда мы отображаем класс UML в модели отображения на другое имя, мы изменяем имя файла, в котором он будет сгенерирован, но не имя класса, который будет сгенерирован в этом файле. По умолчанию высокоуровневый класс генерируется в файле, имя которого соответствует имени этого класса. Значит, для класса UML с именем MyClass преобразование UML - C++ сгенерирует файлы MyClass.h и MyClass.cpp.

Однако вы можете выбрать другое имя для UML-класса при помощи модели отображения. Аналогично тому, как мы переименовали UML-пакет в модели отображения, чтобы сгенерировать другое имя для папки, можно отобразить UML-класс в файл с другим именем. Имя самого класса модель отображения не меняет. Следовательно, чтобы сгенерировать несколько классов в одном файле, достаточно дать им всем одно и то же целевое имя в модели отображения.


Ресурсы

Научиться

Получить продукты и технологии

Обсудить

Об авторах

Сандип Кохли (Sandeep Kohli) - ведущий разработчик и архитектор в рабочей группе Rational Software Architect / Rational Systems Developer в г. Бангалор. Он работал с различными инструментами моделирования Rational, включая Rational Rose, Rational RoseRT и Rational Software Architect и, кроме того, с компиляторами C/C++/Fortran/Ada.

Шрирупа Сен (Sreerupa Sen) работает в IBM в качестве разработчика архитектуры и имеет дело с инструментами UML-моделирования Rational. На протяжении своей карьеры в сфере разработки программного обеспечения ей приходилось работать в различных областях, в том числе она занималась банковскими приложениями, связующим ПО, центрами вспомогательных данных и инструментами моделирования. В IBM она занималась продуктами Rational Software Architect/Rational Systems Developer, особенно связанными с языком C++.

Помощь по сообщениям о нарушениях

Сообщение о нарушениях

Спасибо. Эта запись была помечена для модератора.


Помощь по сообщениям о нарушениях

Сообщение о нарушениях

Сообщение о нарушении не было отправлено. Попробуйте, пожалуйста, позже.


developerWorks: вход


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


При первом входе в developerWorks для Вас будет создан профиль. Выберите информацию отображаемую в Вашем профиле — скрыть или отобразить поля можно в любой момент.

Выберите ваше отображаемое имя

При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

(Должно содержать от 3 до 31 символа.)


Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Оценить эту статью

Комментарии

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Rational
ArticleID=278021
ArticleTitle=Советы по использованию преобразований UML - C++ в Rational Systems Developer и Rational Software Architect
publish-date=12182007
author1-email=sandeep.kohli@in.ibm.com
author1-email-cc=
author2-email=sreerupa.sen@in.ibm.com
author2-email-cc=

Теги

Help
Используйте форму поиска, чтобы найти любой контент с данным тегом в My developerWorks. Используйте ползунок, чтобы отразить больше или меньше тегов.

КнопкаПопулярные теги отображает самые распространенные теги для данной области контента (например: Java, Linux, WebSphere).

Кнопка Мои теги отображает Ваши теги для данной области контента (например: Java, Linux, WebSphere).

Используйте форму поиска, чтобы найти любой контент с данным тегом в My developerWorks. Кнопка Популярные теги отображает самые распространенные теги для данной области контента (например: Java, Linux, WebSphere). Кнопка Мои теги отображает Ваши теги для данной области контента (например: Java, Linux, WebSphere).