VIII Международная конференция по электронным публикациям "EL-Pub2003"

8-10 октября 2003 г., г. Новосибирск, Академгородок

Генерация программного кода приложения при помощи CASE-средств

Зарубин А.А.
Институт Угля и Углехимии, Кемерово

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

Однако сами по себе электронные коллекции не являются готовыми приложениями, так как для извлечения из них данных требуется выполнение некоего программного кода. Без программной составляющей коллекция является просто «свалкой» разнородных данных. Программный код позволяет пользователю коллекции добавлять новую информацию в нее, извлекать данные по заданным алгоритмам, анализировать их.

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

Есть еще одна составляющая этой проблемы. Технология электронной коллекции основывается на объединении распределенных баз данных различных форматов. Доступ к данным может быть получен через язык запросов (SQL) или при помощи программирования с использованием различных языков программирования. Базы данных (БД) в электронных коллекциях играют главную, объединяющую роль, связывая их различные части. Обычно вся предоставляемая информация хранится в базах данных, и зачастую таблицы БД содержат множество связей, индексов, выполняемых процедур и триггеров. Это делает модель данных очень сложным объектом, и малейшее изменение в какой-либо из таблиц может потребовать значительных усилий, в том числе и по перестройке программного кода, отвечающего за работу с БД. Все это приводит к тому, что если раньше один программист мог вести поддержку сразу нескольких информационных систем, то сегодня даже команда профессионалов просто не в состоянии достаточно оперативно отслеживать все необходимые структурные изменения системы без применения специализированных инструментов, одним из которых являются CASE-средства. Использование принципов CASE-моделирования позволяет свести издержки связанные с разработкой и поддержкой программного обеспечения к минимуму [2]. Создание информационной системы при помощи CASE-средства сводится к моделированию в простой и наглядной форме предметной области, т.е. построению так называемой визуальной модели. Кроме этого, современные CASE-средства позволяют также сгенерировать модель данных, на которой отображены все объекты информационной схемы: таблицы, связи, триггеры, а также связать модель БД с объектной моделью.

Построение подобной визуальной модели позволяет снизить риск возникновения ошибок, которые могут привести в дальнейшем к пересмотру все модели и, следовательно, к большим временным задержкам на ее перестройку. При необходимости структурных изменений системы сначала меняется модель, а уж затем на основе этой модели генерируется приложение. Мы подошли к главному вопросу этой статьи: генерация программного кода при помощи CASE–средств. Как осуществляется эта генерация? Насколько использование CASE-систем облегчает труд программиста? Труден ли процесс перегенерации кода при изменениях модели? На эти вопросы попробуем ответить на примере CASE-модели информационной системы «Виртуальный музей угля». На сегодняшний день в Институте Угля накоплена уникальная информация о качественных характеристиках добываемого угля, его производных и других ископаемых, рассредоточенная, однако, по различным источникам. Это значительно затрудняет поиск нужных данных, что говорит о необходимости создания электронного онлайнового музея, который объединит в себе разрозненные сведения, и предоставит возможность быстрого поиска через глобальную сеть интернет.

Автором была разработаны объектная модель музея, содержащая как интерфейс, отражающий работу посетителя с музеем: аутентификация, выбор отдела музея, выбор экземпляра и пр., так и логику программного обеспечения, обеспечивающую работу музея: выбор информации из БД, ее визуализацию, редактирование БД и.т.д и модель данных, отражающая классы таблиц, связи между ними, индексы, ключи. Использованный инструментарий (Rational Rose 2002), позволил связать объектную модель и модель БД воедино и лучше показать логику приложения. Рассмотрим процесс генерации кода на основе объектной модели. Объектная модель музея состоит из нескольких диаграмм: диаграммы вариантов использования (use case diagram), диаграммы классов (class diagram), диаграмм взаимодействия объектов (collaboration diagram) (их несколько) и диаграмм последовательности взаимодействий (sequence diagram) (также несколько). Диаграмма вариантов использования описывает функциональность информационной системы, основные ее действия и возможности, служит функциональной основой модели [1]. Эта диаграмма содержит всевозможные поведения актеров системы.

Рис. 1 Модель вариантов использования

В нашем случае диаграмма содержит одно действующее лицо (актер "visitor"), представляющее собой посетителя музея, который может выполнять определенные действия: аутентифицироваться, выбрать отдел и.т.д. Таким образом, в данной модели на диаграмме вариантов использования изображены лишь всевозможные действия посетителей музея, что не полностью отражает работу программы. Для этого логика каждого из вариантов использования по принципу декомпозиции уточняется более подробными вложенными диаграммами. В нашем случае использовались диаграммы последовательности взаимодействия. Например, вариант использования ChooseExample (Выбор экземпляра) уточняется следующей диаграммой (см. рис. 2.):

Рис. 2 Диаграмма последовательности взаимодействия ChooseExample

Как видно эти диаграммы и описывают программную логику приложения, однако основой для генерации программного кода на выбранном языке программирования является диаграмма классов. Эта диаграмма является центральной частью модели музея. Она содержит все классы музея, разбитые на пакеты (package) (см. рис. 3.). Каждый из пакетов содержит схожие классы: актеров, экранов музея, баз данных и сущностей.

Рис. 3 Пакеты классов

Классы в объектной модели Rational Rose, отраженные на диаграмме классов, полностью соответствуют канонам объектно-ориентированного программирования, - каждый класс содержит атрибуты - какие-либо данные, и операции, выполняющие какие-либо действия над атрибутами. Так же на этой диаграмме показываются некоторые аспекты взаимодействия классов - отношения генерализации, связи и.т.д. Для примера приведем на рис. 4. класс ChooseExampleScreen (экран выбора экземпляра):

Рис. 4 Класс ChooseExampleScreen

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

Сначала необходимо произвести разработку структуры программы, т.е. классы при помощи компонентной диаграммы (Component diagram) разобъем по модулям (пакетам), каждый из которых соответствует пакету из диаграммы классов. Соответственно, родственные классы попадают в один и тот же пакет. Эти пакеты аналогичны packages языка Java (см. рис. 5.).

Рис. 5 Диаграмма компонентов

Далее в каждом из пакетов создаются компоненты (component), каждый из которых соответствует одному классу из диаграммы классов. В спецификациях компонента при генерации необходимо указать импортируемые классы, в том числе и из диаграммы компонентов. Таким образом задаются связи между будущими апплетами.

После того, как мы для каждого класса создали компонент на диаграмме компонентов, напишем программный код главного модуля. Для этого на диаграмме компонентов опять создадим компонент, но при этом укажем ему стереотип Main Program. Это значит, что при генерации кода этот компонент будет являться основой для стартового апплета программы. Теперь все готово к генерации программного кода. Сначала проверим синтаксис класса на отсутствие ошибок. Эта операция доступна в меню Tools->Java->Syntax Check. После этого сгенерируем код, что осуществляется пунктом меню Tools->Java->Generate Code. При этом необходимо указать местоположение для генерируемых файлов с исходными кодами апплетов (см. рис. 6.)

Рис. 6 Указание каталога для генерации исходных файлов

Эту операцию необходимо проделать лишь в первый раз, далее при генерации будет использоваться указанный каталог. Отметим возможность указания jar-файла, т.е. на основе нашего проекта будет создан jar-архив, что облегчает распространение виртуального музея, ведь при установке его на любую машину нужно лишь переписать jar-файл в каталог, на который указывает переменная CLASSPATH. При первой генерации кода в указанном каталоге или архиве создаются java-файлы, при этом классы, расположенные в пакетах записываются в подкаталоги, именующиеся по названию пакетов. Так создается типичная древовидная структура java-проекта. Редактирование полученного исходного кода доступно через пункт меню Tools->Java->Edit Code. Таким образом, в Rational Rose встроен текстовый Java-редактор, что снижает временные задержки программирования проекта. Рассмотрим генерацию на примере того же класса ChooseExampleScreen. Проделываем все вышеуказанные операции, в итоге получается файл следующего содержания:

//Source file: C:\\WORK\\ALEX\\RR\\SOURCE\\Interfaces\\ChooseExampleScreen.java
package Interfaces;
import Entitys.Example;
/**
Экран выбора экземпляра
*/
public class ChooseExampleScreen
{
/**
ID отдела
*/
private int NumDepart;
private Example Example;
/**
@roseuid 3E61EAF700C6
*/
public ChooseExampleScreen()
{
}
/**
@param iNumDepart
@return boolean
@roseuid 3DB2A57B02F7
*/
public boolean InitScreen(int iNumDepart)
{
return true;
}
/**
@param iExample
@roseuid 3DD7DC1803B1
*/
public void SetExample(Example iExample)
{
}
}

Как видно, Rational Rose создал структуру апплета: объявил переменные, импорт классов, определения функций, автоматически сгенерировал конструктор. Мало ли этого? Можно с уверенностью заявить, что это составляет 50% будущего апплета. Остается дописать содержимое функций, и вот тут на помощь приходит диаграмма последовательности взаимодействия, приведенная на рис. 2. Хотя эта диаграмма и не генерирует автоматически исходный код (надеемся, что в скором будущем такая возможность будет реализована), однако она показывает функциональное поведение апплета. Опираясь на нее, дописываем апплет. Сначала класс ChooseDepartScreen создает экземпляр класса ChooseExampleScreen:

ChooseExampleScreen theChooseExampleScreen=new ChooseExampleScreen();

При этом автоматически выполняется конструктор ChooseExampleScreen, который в данном случае пустой. Затем из класса ChooseDepartScreen выполняется функция инициализации экрана ChooseExampleScreen:

theChooseExampleScreen.InitScreen(NumDepart);

где NumDepart - это переменная, содержащая идентификатор выбранного отдела музея. Функция InitScreen выполняет следующие действия:

NumDepart=iNumDepart; //присваиваем внутренней переменной номер отдела
...
//выполняем функции по визуальному оформлению апплета
...
InputNumExampleScreen theInputNumExampleScreen=
new InputNumExampleScreen(this.canvas);
theInputNumExampleScreen.InitScreen(NumDepart);

Таким образом, объект theChooseExampleScreen создает в свою очередь экземпляр класса, отвечающего за ввод номера экземпляра пользователем, и вызывает метод InitScreen для инициализации экрана, при этом при создании экземпляра theInputNumExampleScreen передается канва объекта theChooseExampleScreen; это нужно для того, чтобы диалог выбора номера экземпляра прорисовывался на канве апплета ChooseExampleScreen. Далее управление передается объекту theInputNumExampleScreen, который получает через интерфейс (класс) БД экземпляров список экземпляров данного отдела, ожидает реакции пользователя и возвращает выбранный экземпляр объекту theChooseExampleScreen нижеследующим вызовом:

theChooseExampleScreen.SetExample(Example);

Эта функция присваивает внутренней переменной Example переданное объектом theInputNumExampleScreen значение, создает объект theExampleScreen, и инициализирует его с передачей в качестве параметра объекта Example:

public void SetExample(Example iExample)
{
Example=iExample;
ExampleScreen theExampleScreen=new ExampleScreen();
theExampleScreen.InitScreen(Example);
}

После выполнения этой функции управление работой системы переходит к объекту theExampleScreen. В итоге мы получили работающий апплет с минимумом написанного вручную программного кода. После доработки кода всех апплетов, необходимо лишь дополнить код главной программы, в нашем случае его работа будет заключаться в создании экземпляра класса visitor:

public static void main(String args[]) {
visitor thevisitor = new visitor();
}

Конструктор объекта thevisitor продолжит выполнение программы. Как мы видим, использование технологии CASE существенно облегчает процесс разработки программных продуктов. Современные CASE-средства позволяют автоматически сгенерировать достаточно большую часть программного кода, а время, потраченное на разработку диаграмм последовательности взаимодействия, с лихвой окупается четкой постановкой алгоритмов функциональных возможностей будущей программы. При разработке же динамичных программных комплексов (т.е. при частом изменении внутренней структуры проекта) без применения CASE-моделирования вообще трудно обойтись, ведь всегда есть возможность при изменении каких-либо классов модели перегенерировать исходные коды, при этом все внесенные ранее изменения автоматически сгенерированного кода сохранятся. К тому же существует возможность двухсторонней синхронизации кода и модели, т.е. по измененному программному коду можно автоматически изменить диаграмму классов. Повторение такой процедуры несколько раз называется итерационным моделированием (round-trip modeling [4]), которое составляет основу постепенного уточнения постановки задачи и согласования требований, предъявляемых к программе, с имеющимися ресурсами. В итоге можно сделать вывод: при разработке динамичных, достаточно сложных информационных систем необходимо использование CASE-средств, при этом процесс генерации программного кода значительно облегчается.

Литература

  1. Боггс У., Боггс М. UML и Rational Rose. - М.:Издательство "Лори", 2000 - 582 с.
  2. Фаулер М., Скотт К.. UML. Основы. - Пер. с англ. - СПб:Символ-Плюс, 2002. - 192с.
  3. Фролов А. и Фролов Г. Базы данных в интернет. - М. Издательско-торговый дом "Русская Редакция", 2000 - 432 с.
  4. www.rational.com

Ваши комментарии
Обратная связь
[ICT SBRAS]
[Головная страница]
[Конференции]

© 1996-2000, Институт вычислительных технологий СО РАН, Новосибирск
© 1996-2000, Сибирское отделение Российской академии наук, Новосибирск