Проектирование на Rose Delphi Link

Большаков Олег

Компания Rational Software уже несколько лет является лидером в области создания инструментальных средств для проектирования, разработки, тестирования и сопровождения программного обеспечения. Основным продуктом в линейке Rational является CASE-средство Rational Rose. Rational Rose поддерживает визуальное объектно-ориентированное моделирование (UML), поддерживает генерацию кода и обратное проектирование (построение модели по программному коду) для многих языков программирования, позволяет строить объектную модель разрабатываемой программной системы, определять спецификации классов, объектов, атрибутов и операций (подробнее см. "Программист" №№ 2, 3, 5/6 за 2001 год).

Так как Rational Rose обладает всеми необходимыми характеристиками для проектирования архитектуры системы любого масштаба, напрашивается идея использования Rose с такой мощной и популярной системой программирования, как Delphi. В стандартной поставке Rational Rose не предусмотрена возможность работы с Delphi, но Rational Software ведет программу по поддержке сторонних производителей программ-мостов (Links) между Rose и другими средствами разработки. В рамках этой программы фирмой Ensemble Systems была разработана программа-мост Rose Delphi Link (RDL), связывающая Rational Rose и Delphi. Основные функции RDL - генерация кода и обратное проектирование. Следует помнить, что генерируемый RDL код не содержит реализацию функциональности! Генерируются только декларативные элементы: определения классов, интерфейсов, записей, типов, директивы видимости и т.д.

Дистрибутив Rose Delphi Link можно скачать с сайта фирмы фирмой Ensemble Systems, размер - около 8 МБ. Установка RDL стандартная, никаких сложностей не вызывает. После инсталляции программы в Rational Rose в меню Tools появляется новый пункт Ensemble Tools -> Rose Delphi Link (рис.1).

Рисунок 1. Пункт меню RDL

  1. Прежде чем переходить к рассмотрению Rose Delphi Link, напомню основные этапы работы в среде Rational Rose. Как правило, используется следующий подход:
    Определение требований к системе и построение модели взаимодействия элементов системы (Use Case Diagram и Collaboration Diagram). Для детализации Use Case используются Sequence Diagram. На этих диаграммах отображаются объекты предметной области, участвующие в бизнес-процессах. Эти диаграммы не влияют на генерируемый код.
  2. Построение аппаратной модели системы (Deployment Diagram). На этой диаграмме отображается модель системы в аппаратной реализации. Диаграмма не влияет на код, генерируемый RDL.
  3. Разработка объектной модели системы (определение классов, их взаимодействий, атрибутов, операций). Параллельно с разработкой диаграммы классов, как правило, разрабатывается диаграмма компонентов (Component Diagram), которая отображает взаимодействие файлов, модулей, дополнительных библиотек, использующихся в системе. Диаграмма компонентов также не влияет на генерацию кода.
  4. Генерация кода программы.
    На генерацию кода влияют только диаграммы классов, поэтому в рамках данной статьи мы будем рассматривать только диаграммы секции Logical View. Особенности построения других диаграмм опущены. Перечисленные этапы проектирования в среде Rational Rose применяются для разработки модели и генерации кода на различных языках, поддерживаемых средой Rose. Но в Delphi есть особенность, существенно отличающая разработку в Delphi от разработки в других средах программирования: программирование пользовательского интерфейса. Не секрет, что в Delphi разработка большей части программ начинается именно с проектирования интерфейса пользователя, а при дальнейшем программировании - его существенного изменения. Поэтому использовать стандартный подход Rational Rose не совсем удобно. Для решения этой проблемы компания Ensemble Systems предлагает следующую методологию проектирования:

Рисунок 2. Методология проектирования с использованием RDL

Основная идея такого подхода состоит в использовании обратного проектирования (Round-trip engineering): все изменения, сделанные на уровне программного кода в Delphi, отображаются в объектной модели, построенной в Rose, и наоборот, при изменении классов, методов и т.п. в объектной модели Rose, соответственно, корректируется программный код. Обратите внимание на пару стрелок, которые соединяют третий и четвертый блок. Как раз эти стрелки и отображают процесс обратного проектирования.
Рассмотрим основное окно Rose Delphi Link (рис. 3). Интерфейс достаточно прост, он содержит:
· меню, содержащее команды для работы с проектом, настройки опций и вызова помощи;
· панели, на которых в виде деревьев отображаются иерархические структуры моделей Rose и Delphi;
· кнопка обновления объектных деревьев, кнопки обратного проектирования (Update All) и прямого проектирования, т.е. генерации кода (Update All->).

Рисунок 3. Основное окно Rose Delphi Link

Основное окно RDL является дочерним по отношению к главному окну Rational Rose и постоянно находится поверх этого окна, сворачивается так же как дочернее окно, что, несомненно, очень удобно.
Перед тем как разбирать конкретный пример, рассмотрим подробнее пункты меню Rose Delphi Link.
File -> Open Project - служит для открытия в RDL созданного проекта Delphi. При открытии проекта в окне RDL отображаются объектные деревья открываемого проекта.
File -> New Project - при выборе этого пункта меню RDL предлагает создать пустой Delphi-проект. Файл проекта, создающийся в этом случае, содержит только декларативные элементы, необходимые для минимальной программы Delphi (program, begin, end). Новый проект стоит создавать в случае, если программа не содержит графического пользовательского интерфейса, например, динамическая библиотека. Правда, в этом случае в генерируемый код нужно будет внести корректировку - заменить program на library. С помощью контекстного меню можно создавать модули (unit) и дополнительные директории для модулей. Создаваемые таким образом модули также содержат только минимальную реализацию (uses, interface, implementation, end). После создания модуля, при последующей генерации кода, в секцию uses файла проекта добавляется объявление нового модуля.
Пункты меню View и Help стандартны, и в описании в рамках данной статьи не нуждаются.

Теперь воспользуемся приведенной выше методикой проектирования и разработаем программу и соответствующую ей модель Rose. Для примера возьмем программу, заполняющую два числовых массива размером 5 на 5 случайными числами, а также реализующую некоторые математические функции по их обработке. Программа должна выполнять следующие функции:

  • Заполнять массивы случайными числами в пределах от 1 до 10;
  • Вычислять сумму элементов каждого массива;
  • Определять среднее арифметическое значение элементов;
  • Очищать массивы (инициализировать их нулями).
    Начнем с разработки пользовательского интерфейса в Delphi. В результате незамысловатых действий мышкой у меня получилась вот такая программа, которая пока еще не выполняет никаких действий (рис. 4).

Рисунок 4. Интерфейс разрабатываемой программы

Сохраним этот проект с именами модулей, предлагаемыми Delphi по умолчанию, откроем новый проект Rational Rose, и запустим Delphi Rose Link. Выберем пункт меню Open Project, и откроем только что сохраненный в Delphi проект. В окне RDL отобразятся деревья объектов модели Rose и проекта Delphi (рис. 5).

Рисунок 5. Проект Delphi, открытый в RDL

Левое дерево объектов - это объекты модели Rose, правое дерево - это объекты, объявленные в исходном коде Delphi. Обратите внимание на красные восклицательные знаки слева от значков, обозначающих объекты. Они обозначают различия между кодом Delphi и моделью Rose. Сейчас отмечены все значки, так как модели в Rose пока еще вообще не существует.
Следующий шаг - генерация модели Rose по исходному коду. Для начала генерации нужно нажать кнопку Update All. В случае успешной генерации восклицательные значки у объектов исчезают, что означает, что модель Rose для каждого объекта соответствует исходному коду Delphi. Чтобы посмотреть историю сообщений генерации, надо выбрать пункт меню View -> Messages. В открывшемся окне будет отображен достаточно подробный лог сообщений RDL, выводимых при генерации модели или исходного кода.
Свернем Rose Delphi Link, и в браузере объектов Rose выберем ветку Logical View. Видим два появившиеся пакета: <>Unit1, который содержит объектную модель кода из модуля Unit1.pas, и External References, содержащий объекты Delphi, которые объявлены в модулях вне текущего проекта (объекты библиотеки VCL).
Теперь откроем в среде Rose диаграмму классов, соответствующую модулю Unit1 (Logical View -> Unit1 -> Overview). В первоначальном виде на диаграмме представлена немножко запутанная объектная модель, которую мы приведем в порядок, аккуратно расположив объекты согласно их иерархии (рис. 6).

Рисунок 6. Модель объектов модуля Unit1

Когда интерфейс разрабатываемой программы достаточно сложен и включает не один десяток элементов, объектная модель получается несколько перегруженной. Для того чтобы разгрузить модель, можно удалить из модели некоторые несущественные элементы. Удалять элементы нужно только из диаграммы, так как в этом случае они удаляются только визуально. При удалении из браузера объекты удаляются окончательно, и это влечет за собой изменение генерируемого RDL кода.
Теперь перейдем к следующему шагу: разработке объектной модели, реализующей заданную выше функциональность программы. Классы, их атрибуты и методы реализуем в отдельном модуле, в основном модуле будем создавать экземпляры классов, а в обработчике событий нажатий кнопок пропишем вызовы методов этих классов.

Создадим новый модуль. Сделать это можно и в Delphi, и в Rose, и в RDL, но для чистоты эксперимента создавать все будем только в RDL. В Rose активизируем окно RDL и щелкнем правой кнопкой мыши по корневому элементу в дереве объектов модели Rose - в нашем случае это Model1.mdl. В контекстном меню выберем New -> Unit. Откроется окно редактора компонента (Component Editor) (рис. 7). На вкладке General указывается имя модуля (Unit2), и комментарий к создаваемому модулю, который при кодогенерации будет вставлен в модуль как комментарий. На вкладке Detail указывается вид (kind) компонента, и путь к исходному файлу. На вкладке Code Preview можно посмотреть код, который будет сгенерирован RDL для данного модуля. Выключение переключателя Allow Code/Model Updates запрещает генерацию кода и обновление модели для выбранного элемента.

Рисунок 7. Редактор компонента

После нажатия кнопки Ok видим, что в окне RDL появился значок, обозначающий новый модуль, и рядом с ним восклицательный знак, сигнализирующий о том, что модель Rose и код Delphi не синхронизированы. Обновим код Delphi, нажав кнопку Update All->. Теперь нужно переключиться на Delphi. Видим окно, предупреждающее, что модуль был изменен (рис. 8). Для загрузки обновленного модуля нажмем Ok.

Рисунок 8. Сообщение Delphi об изменении файла проекта

Теперь откроем только что сгенерированный модуль Unit2.pas. Можно убедиться, что генерация кода прошла успешно - объявлены все необходимые ключевые слова, вставлен комментарий. Следующий шаг - моделирование классов и их методов в этом модуле. Перейдем в Rose, и активизируем окно RDL. В дереве объектов выведем контекстное меню на объекте Unit2 и выберем пункты New -> Class. Появляется окно редактора класса (Class Editor) (рис. 9). На вкладке General нужно указать имя класса (Name), вид (Kind), видимость (Visibility) и комментарий к классу (Documentation). В нашем случае класс будет называться TMassiv, область видимости для него - Public.

Рисунок 9. Редактор класса

Для создания всех методов и атрибутов класса будем пользоваться пунктом меню New в контекстном меню класса в дереве объектов RDL. Редакторы атрибутов и методов в основном аналогичны редактору класса, поэтому подробности создания опустим. Создадим следующие атрибуты и методы (все методы с директивами видимости Public, атрибут M имеет видимость Private):
M: array [1..5, 1..5] of Integer; procedure Init; // Инициализация массива procedure FillMassiv; // Заполнение массива случайными числами procedure CalcSum; // Подсчет суммы элементов массива procedure CalcSr; // Подсчет среднего значения элементов массива function GetElement(X, Y: integer): Integer; // Получение элемента массива (x,y) Также создадим метод для класса TForm1, который будет заполнять компоненты TMemo, расположенные на форме, элементами из массивов:
procedure GetMassiv;

В создании методов с параметрами есть некоторая особенность. Сначала метод создается обычным способом, затем, в дереве объектов RDL, в контекстном меню на методе, для которого предлагается указать параметр, выбирается пункт New -> Parameter и указывается имя параметра, его тип и комментарий к нему. После создания класса обратите внимание на диаграмму классов для модуля Unit2 в Rose - наш класс отображен в соответствии со спецификацией UML (рис. 10).

Рисунок 10. Диаграмма классов с созданным классом

Итак, класс создан, точнее его оболочка, пока без реализации. Теперь в основном модуле Unit1 создадим два экземпляра этого класса. Объявим их как M1 и M2 в секции Public класса TForm1. Это делается выбором нужных пунктов в контекстном меню дерева объектов и указанием параметров в редакторе атрибутов. Измененная диаграмма, где в классе TForm1 показаны объявленные экземпляры класса, изображена на рис. 11.

Рисунок 11. Экземпляры класса, объявленные в секции public класса TForm1

Итак, модель построена, и теперь нужно сгенерировать окончательный код. В окне RDL жмем Refresh, Update All-> и переходим в среду Delphi. Теперь надо написать код, реализующий функциональность, и откомпилировать программу. При заполнении методов кодом иногда требуется добавить локальные или глобальные переменные. Это можно сделать в RDL, но лучше реализовать эти переменные в коде, а затем обновить модель Rose по исходному коду Delphi (Update All). Если в модели были удалены некоторые элементы, а в коде они уже реализованы, этот код заключается между директивами компилятора {$IFDEF DELETED} и {$ENDIF}. После реализации всего исходного кода в Delphi вернемся в RDL и еще раз выполним обратное проектирование, нажав Refresh и Update All. Класс TForm1 изменился - в нем появились методы - обработчики событий кнопок (рис. 12). В нашем случае это окончательный вариант диаграммы классов и всей модели в целом.

Рисунок 12. Окончательный вариант диаграммы классов для модуля Unit1

Окончательный исходный код программы и построенную модель Rose можно скачать отсюда.

В рассмотренном примере мы следовали методике разработки приложений, предложенной разработчиком Rose Delphi Link, и в результате получили объектную модель системы. Все классы и диаграммы, описывающее деятельность системы были спроектированы в Rational Rose с помощью программы Rose Delphi Link. Итак, выделим основные преимущества совместного использования RDL и Rational Rose:

  • быстрое и удобное создание прототипа пользовательского интерфейса;
  • возможность получить подробную модель интерфейсных классов, и на ее основе выделить принципиальные архитектурные особенности системы;
  • возможность сопоставить классы с функциональными требованиями к системе;
  • возможность создания управляющих классов в моделях Rational Rose с последующей генерацией кода в Delphi;
  • полная поддержка жизненного цикла разрабатываемой программной системы при использовании других продуктов компании Rational.

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

Литература

1. Вендров А.М. Проектирование программного обеспечения экономических информационных систем. - М.: Финансы и статистика, 2000 г.
2. Трофимов С.А. CASE-технологии: практическая работа в Rational Rose - "Издательство БИНОМ", 2001 г.
3. Буч Г., Рамбо Д., Джекобсон А. Язык UML. Руководство пользователя: Пер. с англ. - М.


Страница сайта http://www.interface.ru
Оригинал находится по адресу http://www.interface.ru/home.asp?artId=4716