2) ImplementationType - позволяет использовать простые типы вместо определения класса, устанавливаемого Rational Rose по умолчанию. При задании этого параметра создается директива typedef.
3) ClassKey - используется для задания типа класса, такого как class, struct, или union. Если тип не указан, то создается класс.
4) GenerateEmptyRegion - свойство указывает, как будет создаваться пустой раздел protected: None - пустой раздел не будут создан; Preserved - пустой раздел будет создан, если будет установлено свойство «preserve=yes»; Unpreserved — пустой раздел будет создан, если будет установлено свойство «preserve=no»; All — всегда будет создаваться.
5) PutBodiesInSpec - если установлено как true, то в заголовочный файл попадет и описание тела класса. Используется для компиляторов, которым необходимо определение шаблона класса в каждом компилируемом файле.
6) GenerateDefaultConstructor - позволяет установить, необходимо ли создавать конструктор для класса по умолчанию. Может принимать следующие значения: DeclareAndDefine - создается определение для конструктора и скелет конструктора в теле класса; Declare Only - создается только определение; DoNotDeclare - не создается ни определения, ни скелета конструктора.
7) DefaultConstructorVisibility - устанавливает раздел, в котором будет определен конструктор по умолчанию: public, protected, private, implementation.
8) InlineDefaultConstructor - устанавливает, будет ли конструктор по умолчанию создаваться как inline подстановка. Если конструктора по умолчанию нет, то данное свойство не оказывает на код никакого эффекта.
9) ExplicitDefaultConstructor - устанавливает конструктор по умолчанию как explicit (явно заданный).
10) InlineRelationalOperations - определяет, будут ли функции операторов сравнения создаваться как inline подстановка.
11) GenerateStorageMgmtOperations - определяет, будут ли переопределяться операторы new и delete в классе.
12) StorageMgmtVisibility - определяет раздел, в который будут помещены операторы new и delete.
13) InlineStorageMgmtOperations - определяет, будут ли операторы new и delete определены как inline подстановка.
14) GenerateSubscriptOperation - определяет, будет ли переопределен оператор [].
15) Subscript Visibility определяет - раздел, в который будет помещен оператор [].
16) SubscriptKind - определяет вид функций оператора []: Common - обычная, Virtual - виртуальная, Abstract - абстрактная.
17) SubscriptResultType - определяет тип возвращаемого выражения для
оператора [].
18) InlineSubscriptOperation - определяет, будет ли оператор [] определен как inline подстановка.
19) GenerateDereferenceOperation - определяет, будет ли переопределен оператор *.
20) Dereference Visibility - определяет раздел, в который будет помещен оператор *.
21) DereferenceKind - определяет вид функций оператора *: Common - обычная, Virtual - виртуальная, Abstract - абстрактная.
22) DereferenceResultType - определяет тип возвращаемого выражения для оператора *.
23) InlineDereferenceOperation - определяет, будет ли оператор * определен, как inline подстановка.
24) GeneratelndirectionOperation - определяет, будет ли переопределен оператор ->.
25) IndirectionVisibility - определяет раздел, в который будет помещен оператор ->.
26) IndirectionKind - определяет вид функций оператора ->: Common - обычная, Virtual - виртуальная, Abstract - абстрактная.
27) IndirectionResultType - определяет тип возвращаемого выражения для оператора ->.
28) InlinelndirectionOperation - определяет, будет ли оператор -> определен как inline подстановка.
29) GenerateStreamOperations - определяет, будут ли переопределены операторы потоков (« и »).
2.1.5 Выбор класса, компонента или пакета
При генерации программного кода за один раз можно создать класс, компонент или целый пакет. Программный код генерируется с помощью диаграммы или браузера. При генерации кода из пакета можно выбрать либо пакет Логического представления на диаграмме Классов, либо пакет представления Компонентов на диаграмме Компонентов. При выборе пакета Логического представления генерируются все его классы. При выборе пакета представления Компонентов генерируются все его компоненты.
Программный код можно генерировать одновременно для нескольких классов, компонентов или пакетов. На диаграмме с помощью клавиши Ctrl выберите классы, компоненты или пакеты, для которых нужно сгенерировать программный код, а затем - соответствующую команду генерации в меню.
2.1.6 Генерация программного кода
Если у вас установлены Rose Professional или Rose Enterprise, то в меню Tools предлагается несколько вариантов, специфичных для конкретного языка программирования (см. рис. 5.3).
Рисунок 5.3 - Пункты меню генерации кода
Чтобы показать или скрыть эти пункты меню, выберите пункт Add-Ins → Add-Ins (Надстройки → Менеджер надстроек). В диалоговом окне Add-In Manager (см. рис. 5.4) с помощью флажков покажите или скройте нужные варианты для различных языков.
Рисунок 5.4 - Менеджер надстроек Add-Ins
Генерация программного кода в среде IBM Rational Rose 2003 возможна для отдельного класса или компонента. Для этого нужный элемент модели предварительно следует выделить в браузере проекта и выполнить операцию контекстного меню: Tools→C++→Code Generation - (Язык C++→Генерировать код). В результате этого будет открыто диалоговое окно с предложением выбора классов для генерации программного кода на выбранном языке программирования (рис. 5.5). После выбора соответствующих классов и нажатия кнопки OK программа IBM Rational Rose 2003 выполняет кодогенерацию.
Рисунок 5.5 - Окно выбора классов для генерации программного кода
Затем происходит компиляция и выдается окно статуса (Code Generation Status). Здесь можно увидеть информацию о том, какой класс был закодирован и количество ошибок и предупреждений (рис. 5.6). Если у вас произошла, какая-либо ошибка или же предупреждение, то их можно увидеть на рабочем поле в Rational Rose, для этого и существует самое нижнее окно, в нем передаются все ваши действия и ошибки, произошедшие в ходе кодогенерации.
Рисунок 5.6 – Окно статуса компиляции
2.1.7 Результаты генерации
В результате кодогенерации Rational Rose создает два файла с расширением “.h” и “.cpp”, названия у них те же, что и название класса. Итак, выполнив эти действия, нажимаем правой клавишей на класс, появляется окошко, в нем ищем “С++”, и видим два пункта Browse Header и Browse Body, и в зависимости от того какой из файлов нам нужен “.h” (заголовочный) или “.cpp” (непосредственно реализация), выбираем их. Эти файлы открываются с помощью блокнота и теперь легко можно увидеть скелет класса, с различными комментариями, которые писали вы на диаграммах, и комментарии которые вставляет сама Rose. Теперь можно открыть один из файлов в С++ и доработать класс, описать работу функций, добавить различные нововведения.
Следует заметить, что при установленной на компьютер разработчика интегрированной среды сгенерированные файлы с текстом программного кода автоматически открываются в этой среде после двойного щелчка на пиктограмме этих файлов. Тем не менее, лучше копировать содержимое этих файлов в предварительно созданные программные проекты для полного контроля в этих средах процесса программирования и отладки приложений.
Сгенерированные программой IBM Rational Rose 2003 файлы с текстом программного кода содержат минимум информации. Для включения дополнительных элементов в программный код следует изменить свойства генерации программного кода, установленные по умолчанию.
В заключение следует отметить, что эффект от использования средства IBM Rational Rose 2003 проявляется при разработке масштабных проектов в составе команды или проектной группы. Однако ситуация покажется не столь тривиальной, когда станет необходимо выполнить проект с несколькими десятками вариантов использования и сотней классов. Именно для подобных проектов явно выявляется преимущество использования средства IBM Rational Rose 2003 и нотации языка UML для документирования и реализации соответствующих моделей.
3 Пример сгенерированного кода на язык программирования С++
{Class Diskr_analiz}
//## begin module%1.5%.codegen_version preserve=yes
// Read the documentation to learn more about C++ code generator
// versioning.
//## end module%1.5%.codegen_version
//## begin module%470F79570399.cm preserve=no
// %X% %Q% %Z% %W%
//## end module%470F79570399.cm
//## begin module%470F79570399.cp preserve=no
//## end module%470F79570399.cp
//## Module: Diskr_analiz%470F79570399; Pseudo Package body
//## Source file: C:\Program Files\Rational\Rose\C++\source\Diskr_analiz.cpp
//## begin module%470F79570399.additionalIncludes preserve=no
//## end module%470F79570399.additionalIncludes
//## begin module%470F79570399.includes preserve=yes
//## end module%470F79570399.includes
// Diskr_analiz
#include "Diskr_analiz.h"
//## begin module%470F79570399.additionalDeclarations preserve=yes
//## end module%470F79570399.additionalDeclarations
// Class Diskr_analiz
Diskr_analiz::Diskr_analiz()
//## begin Diskr_analiz::Diskr_analiz%470F79570399_const.hasinit preserve=no
//## end Diskr_analiz::Diskr_analiz%470F79570399_const.hasinit
//## begin Diskr_analiz::Diskr_analiz%470F79570399_const.initialization preserve=yes
//## end Diskr_analiz::Diskr_analiz%470F79570399_const.initialization
{
//## begin Diskr_analiz::Diskr_analiz%470F79570399_const.body preserve=yes
//## end Diskr_analiz::Diskr_analiz%470F79570399_const.body
}
Diskr_analiz::Diskr_analiz(const Diskr_analiz &right)
//## begin Diskr_analiz::Diskr_analiz%470F79570399_copy.hasinit preserve=no
//## end Diskr_analiz::Diskr_analiz%470F79570399_copy.hasinit
//## begin Diskr_analiz::Diskr_analiz%470F79570399_copy.initialization preserve=yes
//## end Diskr_analiz::Diskr_analiz%470F79570399_copy.initialization
{
//## begin Diskr_analiz::Diskr_analiz%470F79570399_copy.body preserve=yes
//## end Diskr_analiz::Diskr_analiz%470F79570399_copy.body
}
Diskr_analiz::~Diskr_analiz()
{
//## begin Diskr_analiz::~Diskr_analiz%470F79570399_dest.body preserve=yes
//## end Diskr_analiz::~Diskr_analiz%470F79570399_dest.body
}
Diskr_analiz & Diskr_analiz::operator=(const Diskr_analiz &right)
{
//## begin Diskr_analiz::operator=%470F79570399_assign.body preserve=yes
//## end Diskr_analiz::operator=%470F79570399_assign.body
}
int Diskr_analiz::operator==(const Diskr_analiz &right) const
{
//## begin Diskr_analiz::operator==%470F79570399_eq.body preserve=yes