Сейчас Business Component Prototyper представляет собой инструментарий для разработки прототипных приложений, предлагаемый вместе с IBM SanFrancisco v 1.4. Он призван помочь неопытным разработчикам SanFrancisco создавать небольшие прототипы, используя модель программирования базового уровня системы SanFrancisco, обходясь при этом без многофункционального набора инструментальных средств, применяемых для разработки приложений. IBM SanFrancisco - это набор компонентов на базе Java, который позволяет разработчикам собирать серверные бизнес-приложения из существующих фрагментов, а не создавать их с самого начала.
Использование объектной технологии для разработки приложений постепенно приобретает массовый характер. Несмотря на это, как будет показано ниже, расчеты на то, что данная технология на порядок увеличит производительность, пока не оправдываются.
Постепенно становится все очевиднее, что одних лишь объектно-ориентированных языков и объектно-ориентированных методов анализа не достаточно. Добиться поставленной цели можно с помощью стандартизации, готовых к использованию компонентов и сред разработки, в которых основные фрагменты кода «автоматически» генерируются по требованию разработчика. Стандартизация не составляет труда, если все разработчики используют один и тот же язык программирования. Большая часть сообщества информационных технологий выбрала язык программирования Java, а спецификации на JavaBeans и Enterprise JavaBeans во многом обеспечат требуемое единство. В качестве коммуникационного протокола для документов и структурированных данных был создан XML (Extensible Markup Language). На основе этих стандартов стали разрабатываться такие серьезные оболочки компонентов, как SanFrancisco компании IBM.
Способны ли компоненты решить проблему?
Как одного из первых создателей технологии компонентов стоит назвать Бреда Кокса [1], разработавшего Software-IC. Лишь через десять лет после того, как он опубликовал свою основополагающую книгу, его идеи, наконец, воплотились в реальность.
Дэвид Тейлор [2] приводит интересную аргументацию, объясняя почему инструментарий CASE (автоматизированного проектирования систем) не способен стать решением проблемы. Рассмотрим традиционный процесс разработки, где равное время тратиться на анализ, проектирование, кодирование, тестирование и обслуживание. Представим теперь, что в нашем распоряжении есть объектно-ориентированный CASE-инстурментарий, который способен выполнять анализ и проектирование на 30% эффективнее, сократить до нуля затраты на реализацию и на 30% ускорить разработку и обслуживание. Таким образом, весь процесс разработки станет эффективнее менее, чем на 50%, что далеко от нашей цели, предполагающей увеличение производительности на порядок.
Еще один широко разрекламированный подход - повторное использование. Эдвард Йорден [3] приводит убедительное объяснение того, почему повторное использование в прошлом не приносило большой пользы. Одна из причин, по мнению Йордена, состоит в том, что повторное использование по большей части сводилось к повторному использованию программ или их фрагментов. Повторное использование архитектурных или аналитических решений было бы намного эффективнее, поскольку оно автоматически предполагает повторное использование кода, и могло бы внести существенные коррективы в расчеты производительности, приведенные выше.
Добиться повторного использования архитектурных решений можно за счет использования одной из принятых сейчас компонентных архитектур, к которым, в частности, относятся следующие.
- Спецификации JavaBeans и Enterprise JavaBeans компании Sun.
- Разработанные компанией Microsoft спецификации ActiveX, VBX (расширения Visual Basic) и OCX (OLE Custom Controls).
- Компоненты бизнес-приложений SanFrancisco (на языке Java), созданные компанией IBM.
Компонентные оболочки предусматривают повторное использование и самого кода, и архитектурных решений. Они позволяют упростить повторное использование, поскольку предлагают не только хорошо структурированные и четко ограниченные наборы функций - своего рода «строительные блоки», но также средства, позволяющие быстро и просто эти блоки объединить.
Мы пришли к выводу, что компонентные оболочки помогут значительно увеличить производительность. Если сопроводить эти оболочки хорошим инструментарием разработки, производительность может стать еще выше.
SanFrancisco
Проект IBM SanFrancisco стал очень серьезной работой по созданию компонентной структуры. Его уникальность в том, что это не только промежуточное программное обеспечение, но и большой набор бизнес-компонентов. Детальное описание SanFrancisco можно найти по адресу http://www.software.ibm.com/ad/sanfrancisco. Для читателей, не знакомых с данной оболочкой, в этом разделе приводится очень краткое описание ее многоуровневой структуры.
Рис. 1. Общая структура SanFrancisco |
Как показано на Рисунке 1, SanFrancisco предлагает три уровня кода, который может повторно использоваться разработчиками приложений.
- Базовый уровень, который представляет инфраструктуру и службы, требуемые для создания приложений в распределенной многоплатформенной среде.
- Уровень общеупотребительных бизнес-объектов предлагает реализации часто используемых бизнес-объектов, которые встречаются в самых разных прикладных областях. Общеупотребительные бизнес-объекты могут использоваться в качестве основы для поддержки интероперабельности между приложениями.
- Уровень основных бизнес-процессов предлагает бизнес-объекты и бизнес-логику по умолчанию для избранных «вертикальных предметных областей». Сейчас SanFrancisco предлагает бизнес-компоненты в таких областях, как сета дебиторов (AR), счета кредиторов (AP), главная бухгалтерская книга (GL), управление заказами (продажи и покупки) и управление складом.
Зачем нужны дополнительные инструментальные средства?
Ведущие производители инструментария моделирования и интегрированных сред разработки (IDE) предлагают новые версии своих инструментальных средств, поддерживающих язык программирования Java и UML (Unified Modeling Language) [4].
Многие производители инструментария считают для себя слишком сложным адаптировать инструментальные средства к крупным оболочкам. И тому есть немало причин.
- Некоторые инструментальные средства моделирования и разработки не поддерживают приемлемый уровень масштабирования в тех случаях, когда им приходится импортировать более 2000 компонентов (именно столько предлагает SanFrancisco).
- Технологии генерации кода не способны масштабироваться до уровня столь больших моделей программирования, как модель, определяемая SanFrancisco.
- Диссонанс между инструментарием моделирования и программирования по прежнему весьма значителен.
- Большая часть современного инструментария написана не на Java. В силу чего, зачастую, эти инструментальные средства работают только на одной платформе и имеют жестко определенный набор функций.
- Отсутствует поддержка компонентов как строительных блоков в виде «черного ящика».
- Часто невозможно или очень сложно адаптировать генераторы кода к конкретной оболочке или к требованиям пользователей.
Из-за всех перечисленных проблем хорошие инструментальные средства, предназначенные для оболочки SanFrancisco, практически не создаются, а в тех немногих, которые уже выпускаются, отсутствует ряд необходимых функций.
По-видимому, возникает необходимость в создании новой архитектуры инструментальных средств. Такая архитектура должна использовать компоненты таким же образом, каким она пытается их поддерживать. Она должна применять новые модули создания документов и использовать их для хранения информации о моделях, исходных текстов программ и документации об архитектуре.
Business Component Prototyper
Business Component (BC) Prototyper представляет собой инструментарий создания прототипов и поставляется вместе с SanFrancisco v1.4.5. Он предназначен для того, чтобы помочь разработчикам, впервые столкнувшимся с SanFrancisco, разобраться с моделью программирования базового уровня. Он позволяет создавать пробные прототипы, которые действительно могут работать. BC Prototyper входит в состав системы SanFrancisco в качестве пробного инструментария, поскольку позволяет разработчикам использовать пробную версию SanFrancisco. В этой версии не доступны модели Rational Rose классов SanFrancisco и генератор кода SanFrancisco.
Версия BC Prototyper, описанная в данной статье, имеет более широкие функции, чем выпускаемый инструментарий, и, в первую очередь, позволяет использовать компоненты SanFrancisco. Данная версия не предназначена для широкого использования.
На первый взгляд BC Prototyper - это просто интегрированная среда разработки, охватывающая широкий диапазон операций, от моделирования объектов до развертывания приложений. Она включает в себя инструментарий моделирования, среду программирования, генератор кода, модуль создания графического пользовательского интерфейса и утилиты SanFrancisco. Система имеет архитектуру строительных блоков, что позволяет быстро адаптироваться к меняющимся требованиям. В этой архитектуре использованы идеи, составляющие основу новых разработок, таких как Java-beans (бобы), самоанализ Java и XML. BC Prototyper активно применялся и для его собственной разработки.
Business Component Prototyper - это инструментарий, написанный исключительно на Java, который обладает некоторыми возможностями интегрированной среды разработки, функциями генерации кода и интерфейсами ко многим утилитам SanFrancisco.
Общее описание. Сначала мы остановимся на общем описании функциональности BC Prototyper в его конфигурации SanFrancisco. Затем расскажем о гибких функциях BC Prototyper и о том, как можно использовать этот инструментарий в других средах.
Основная часть этого инструментария, код и пользовательский интерфейс генерируются из модели самого инструментария. Изменяя метамодель (с помощью BC Prototyper), можно модифицировать и эту часть инструментария.
Функциональность BC Prototyper можно расширить, создавая подключаемые адаптеры, которые поддерживают простой интерфейс, аналогичный «бобам».
Генератор кода обращается к информации о пользовательской модели, используя для этого возможность самоанализа Java в объектах метамодели. Шаблоны генерации кода написаны на XML, что позволяет потребителям легко их настраивать. Кроме того, пользователи могут добавлять новые шаблоны кодирования.
BC Prototyper поддерживает процесс создания компонентов из файлов .class, написанных на Java. Например, компоненты BC Prototyper созданы для большинства общеупотребительных бизнес-объектов IBM SanFrancisco. Они могут теперь использоваться в BC Prototyper как своего рода «черные ящики». Таким образом можно избежать необходимости загружать в инструментарий большие модели.
Часто используемые функции утилит SanFrancisco доступны через подключаемые адаптеры, с которыми связываются кнопки инструментальной панели. Это позволяет быстро и легко выполнять итерации цикла разработки SanFrancisco.
Функции инструментария. Перед тем как приступить к описанию архитектуры BC Prototyper, было бы полезно рассказать о его функциональности. Это будет сделано на примере простого приложения SanFrancisco, разработанного с помощью BC Prototyper.
В данном случае предполагается, что в компании используется множество адресных книг - по одной для каждого сотрудника. Каждая адресная книга может содержать множество адресов. Таким образом, в нашей модели необходимо создать класс AddressBook; а Address - это компонент, взятый из общеупотребительных бизнес-объектов SanFrancisco. Другие классы в модели - это AddressBookController и DescribableDynamicEntity. Класс Controller предоставляет механизм, позволяющей компании работать с тесно интегрированным набором адресных книг. Можно предположить, что в модели используется класс Company; он не видим, поскольку неявно обрабатывается модулем BC Prototyper. Как правило, объекты Company играют центральную роль в любом приложении SanFrancisco; они могут быть организованы в сложную, иерархическую структуру и служить в качестве опорных точек для всех данных приложения. Класс DescribableDynamicEntity - это подкласс класса Entity и, таким образом, объекты его подклассов (AddressBook и AddressBookController) автоматически всегда присутствуют, обрабатываются и распространяются. Кроме того, объекты класса DescribableDynamicEntity и его подклассы могут быть описаны не зависящим от языка образом и к ним динамически можно добавлять атрибуты. Наконец, интерфейс Distinguishable позволяет присваивать экземплярам AddressBook идентификаторы (ID), которые могут быть использованы для поиска в экземпляре AddressBookController.
Рис. 2. Окно BC Prototyper |
При запуске инструментария появляется окно, состоящее из трех частей (см. Рисунок 2). Первая часть содержит панель меню и панель инструментов. Кнопки на инструментальной панели показывают основные действия, которые пользователь может выполнять в конфигурации SanFrancisco.
- Создать новый проект
- Загрузить и сохранить проект
- Редактировать свойства проекта
- Создать новый класс
- Импортировать компонент
- Создать связь
- Редактировать выбранные элементы модели (классы или связи)
- Выполнить построение для выбранных компонентов (генерировать сервер, клиент и код графического пользовательского интерфейса, компилировать, генерировать посредников (proxy))
- Добавить имена к пространству имен SanFrancisco
- Запустить приложение
- Остановить приложение
- Начать работу SanFrancisco
- Закончить работу SanFrancisco
- Показать информацию из службы помощи
Вторая часть рабочей области состоит из одной или нескольких панелей с вкладками.
Первая панель содержит две подпанели. Левая подпанель позволяет просматривать модель в виде дерева. Элементы модели можно обновлять, дважды щелкнув на них клавишей мыши, после чего появляется редактор свойств. Правая подпанель отображает загруженную в данный момент модель в графическом виде.
На левой стороне второй панели показан список файлов .java, находящихся в каталоге текущего проекта. С помощью кнопок панели файл можно просмотреть в простом текстовом редакторе или скомпилировать с помощью компилятора javac. Для всех файлов, перечисленных с левой стороны второй панели, может быть сгенерирован посредник. В этой панели можно также просмотреть или изменить сгенерированную информацию об именах, необходимую для распределенной объектной инфраструктуры SanFrancisco.
Третья часть представляет собой окно вывода сообщений, где регистрируются действия, выполняемые инструментарием и отображаются ошибки.
Эта статья не ставит своей целью заменить руководство пользователя по BC Prototyper, поэтому мы не будем описывать, как создавать приложение. Отметим только несколько моментов, которые отличают данный инструментарий от других. Графика модели - это упрощенная форма UML. Каждый, кто способен написать подпрограмму рисования на Java, может заменить графический модуль на тот, который лучше выполняет функции UML.
Импортированные компоненты показаны как классы, выделенные зеленым цветом. На Рисунке 2 - это DescribableDynamicEntity и Address. Импорт компонентов можно начать, нажав кнопку на инструментальной панели. Эти компоненты хранятся в простой файловой структуре. Диалоговое окно файла позволяет выбрать требуемый компонент. Ниже описано, каким образом компоненты конвертируются в формат BC Prototyper из классов SanFrancisco.
Интерфейс Distinguishable на рисунке представлен классом с белым фоном. Интерфейсы импортируются таким же образом, как компоненты. Кроме того, интерфейсы могут содержать фрагменты генерации кода. Это позволяет предлагать для интерфейса Java реализации по умолчанию. Обычно разработчику не приходится писать какой-либо код для реализации интерфейса.
Третье представление предлагает детальную информацию о модели. Изменить элементы дерева можно с помощью редактора свойств, который появляется по двойному щелчку мыши, указывающей на нужный элемент.
Рис. 3. Редактор свойств для атрибутов |
Стоит также отметить возможность настроить код графического пользовательского интерфейса, который сгенерирован модулем BC Prototyper. Для иллюстрации на Рисунке 3 приводится редактор свойств для атрибута bookName класса AddressBook. Из этого примера видно, что bookName будет представлен как текстовое поле с меткой «bookName». Можно изменить тип представления и указать, чтобы метка выводилась слева от текстового поля или как-то иным образом, например, как имя атрибута, к примеру «Book Name». После чего генератор кода создаст соответствующий текст программы.
Заметим, что демонстрация редактора свойств сама по себе является примером настройки представления. Код редактора полностью сгенерирован из метамодели инструментария, описанной ниже.
Когда создание модель завершено, по нажатию кнопки Rebuild, расположенной на инструментальной панели, будет выполнена генерация и компиляция кода и созданы необходимые вспомогательные классы Java в распределенной объектной архитектуре SanFrancisco. Следующий шаг - добавление токенов с информацией об именах вновь определенных классов в конфигурацию имен SanFrancisco с помощью соответствующей утилиты. В случае необходимости серверы SanFrancisco будут запущены автоматически.
Рис. 4. Главное окно, сгенерированное для адресной книги |
После этого можно запускать приложение. На Рисунке 4 показано, как выглядит экрана. Нужно отметить, что все поля в панели Addresses сгенерированы на основе информации из импортированного компонента.
Архитектура BC Prototyper
Базовая структура BC Prototyper очень проста: основу инструментария составляет инструментальная база (toolbase) (см. Рисунок 5). Он содержит ссылку на структуру метамодели и список ссылок на подключаемые адаптеры. Единственная «обязанность» инструментальной базы - уведомлять все подключаемые адаптеры о наступлении событий. Каждый подключаемый адаптер может определить, должен ли он игнорировать данное событие или реагировать на него, возможно порождая иные события.
Рис. 5. Структура BC Prototyper |
Функции подключаемых адаптеров представлены или кнопками на инструментальной панели, или элементами меню. Панель с вкладками, в соответствии со своим названием, содержит панели вкладок. С помощью подключаемых адаптеров можно воспользоваться набором инструментальных средств, к примеру, подпрограммами рисования или генератором кода. Подключаемые адаптеры активируются нажатием на инструментальную панель и выбором элемента меню, или посредством уведомления из инструментальной базы.
В файле .ini перечислены подключаемые адаптеры, которые должны загружаться при запуске инструментария. Внося изменения в этот список, можно менять функции и появление инструментария. Например, если в этот список не добавлять связанные с SanFrancisco подключаемые адаптеры, можно получить автономный инструментарий подготовки прототипов.
Метамодель. Метамодель - это модель моделей. Проще говоря, когда в инструментарии моделирования, таком как BC Prototyper (или Rational Rose), определяется модель, пользователь указывает, какие классы содержаться в модели, а затем для каждого класса называет некоторые характеристики, такие как имя класса и т.д. Кроме того, для каждого класса пользователь определяет атрибуты, методы и связи с другими классами.
Точно также, как можно создать модель для приложения адресной книги, где классами являются AddressBook и Address, можно построить модель на основе информации, которую BC Prototyper использует для хранения информации о моделях. В модели BC Prototyper классами являются ClassHeader, ClassBody, Attribute, Method и т.д., как показано на Рисунке 6. Мы называем эту модель метамоделью BC Prototyper.
Рис. 6. Метамодель BC Prototyper |
Как показано на Рисунке 6, метамодель BC Prototyper - это модель. Как и в случае с другими моделями на основе может быть сгенерирован код. Мы так и поступили, и теперь этот код играет центральную роль в самом инструментарии. Он используется для хранения информации о моделях, определенных пользователями, а сгенерированный код GUI предоставляет пользовательский интерфейс к этому инструментарию (См., например, таблицу свойств на Рисунке 3).
И опять-таки, поскольку метамодель - такая же модель, как и все остальные, ее можно менять также, как и другие модели, хотя не стоит модифицировать структуру или имена классов. По модели можно восстановить и скомпилировать код. При перезапуске BC Prototyper в графическом пользовательском интерфейсе могут быть отражены любые изменения, а значения любых новых атрибутов могут управлять генерацией кода новых приложений.
Если внимательно проанализировать информацию метамодели на Рисунке 6 и в Таблице 1, становится ясно, что многие элементы служат для поддержки оболочки SanFrancisco. С помощью другой метамодели могут поддерживаться другие среды, такие как среда Enterprise JavaBeans или простые автономные приложения.
Как пример подробной информации, которую можно найти в метамодели, Таблица 1 показывает (сгенерированную) документацию для атрибутов в классе Attribute.
Отображение модели на ее представление. BC Prototyper генерирует, если об этом запрашивает пользователь, не только код модели, которая реализует структуру модели так, как она была определена пользователем, но также и графический пользовательский интерфейс, который применяется для создания прототипов и который может использоваться для последующей настройки в производственной версии приложения.
Рис. 7. Режим управления транспортным заказом |
На Рисунке 7 приведен пример управления транспортным заказом. На Рисунке 8 представлена часть сгенерированного пользовательского интерфейса. Этот пример показывает, что для генерации приемлемого интерфейса можно использовать даже более сложную модель. Когда в одной из предпринятых нами многочисленных попыток создать прототип возникал «странный» интерфейс, в предложенной модели всегда обнаруживалась ошибка.
Правила отображения для создания пользовательского интерфейса, перечислены ниже.
- Класс отображается на экземпляр Frame с набором панелей с вкладками.
- Атрибуты класса отображаются на экземпляр TextField, TextArea, Checkbox, Choice или Button вместе с экземпляром Label, если это допустимо.
- Содержащиеся в классе связи один-ко-многим будут отображаться на экземпляр List в содержащем классе. Элемент списка показывает результат применения метода toString() к объекту, который его содержит.
- Для класса, имеющего связь один-к-одному, атрибуты отображаются на панели с вкладками в папке содержащего класса. Суперкласс отображается таким же образом.
- Для всего остального, за исключением содержащих связей, кнопка ссылки (помеченная Details) будет добавляться к родительскому классу.
- Атрибуты и списки могут быть сгруппированы по панелям с вкладками с помощью указания значения TabGroup в панели представления (view tab) атрибута или в редакторе свойств связи.
Утверждается, что отображение на основе этих правил всегда приведет к созданию полезного графического пользовательского интерфейса. Причина в том, что класс должен определять логически согласованное множество концепций, и в окне на экране мы хотим видеть значения отображаемого логически согласованного набора концепций. Таким образом, отображение один-к-одному может быть сгенерировано автоматически, в противном случае в модели не все определено корректно.
Что касается атрибутов, корректное отображение выполняется по умолчанию. Например, атрибут String будет отображаться на экземпляр TextField, а атрибут Boolean - на экземпляр CheckBox. Это отображение может быть изменено с помощью таблицы свойств для атрибута за счет определения иного значения типа представления (view type). Пример приведен на Рисунке 3.
Рис. 8. Отображение класса TransportOrder и папки с панелями |
Применяя эти правила к нашей модели преобразования, мы получаем сгенерированную папку для класса TransportOrder как показано на рисунке 8. Способ, каким атрибуты класса присваиваются группам, где группа отображается на панель с вкладками, нельзя понять из модели, как показано на Рисунке 7. Например, если открыта связь между TransportOrder и LogisticsUnit, в спецификации представления (view specification) видно, что связь должна быть помещена в группу вкладки Goods.
Для производственного приложения генерация кода по умолчанию может оказаться неудовлетворительной. Инструментарий предоставляет два способа адаптировать сгенерированный код к конкретным требованиям.
1. Использовать один из сгенерированных фрагментов или переопределить один из методов структуры.
2. Изменить шаблоны генерации кода.
Если по тем или иным причинам ни один из этих методов не применим, сгенерированные панели могут быть импортированы в инструментарий с помощью программ, позволяющих редактировать изображения, таких как VisualAge for Java компании IBM, применяемых для дальнейшего расширения кода.
Подключаемые адаптеры. Функциональность BC Prototyper можно расширить за счет создания подключаемых адаптеров, которые имеют интерфейс, аналогичный бобам (bean).
Подключаемые адаптеры выполняют конкретные функции, такие как открытие или сохранение модели, добавление информации об именах в пространство имен SanFrancisco, рисование модели в упрощенном UML и так далее.
При старте модуль начальной загрузки BC Prototyper считывает конфигурационный файл и пытается создать экземпляры перечисленных подключаемых адаптеров. Подключаемый адаптер указывает, как сделать так, чтобы он был видим во время своей инициализации с помощью простых операторов, таких как
setUsedAsToolbarButton(true); setUsedAsMenuItem(true);
Эти операторы означают, что подключаемый адаптер будет использоваться как кнопка на инструментальной панели и как функция меню. Каждый подключаемый адаптер также реализует метод run(String s), который будет переключаться, когда пользователь нажимает кнопку на инструментальной панели или щелкает мышью на инструментальной панели и т.д.
Все подключаемые модули имеют ссылку на инструментальную базу. Это позволяет подключаемому адаптеру уведомлять инструментальную базу о событиях, на которые, если необходимо, могут реагировать другие подключаемые адаптеры. Например, подключаемый адаптер может обратиться к инструментальной базе с запросом о многоадресной рассылке измененного события. Все подключаемые адаптеры получат уведомление и, либо выполнят необходимое действие, либо проигнорируют событие.
Подключаемые адаптеры реагируют на событие, выполняя одно действие, и обычно не знают о существовании друг друга. Это значит, что подключаемые адаптеры небольшие и модульные. Примеры функциональности подключаемых адаптеров обсуждались ранее.
Ссылка инструментальной базы может также использоваться для доступа к структуре метамодели, описанной ранее. Эта структура содержит информацию о модели UML, в данный момент загруженной в память.
Модульность подключаемых адаптеров позволяет легко добавлять к инструментарию различные функции. К примеру, подключаемые адаптеры запускают и останавливают SanFrancisco и эти действия обычно представлены в виде кнопок в инструментарии, которые обычно не связаны с функциональностью BC Prototyper. Они представляют собой программу на Java длиной около 20 строк, которая вызывает соответствующую программу запуска и остановки SanFrancisco. Пользователь BC Prototyper может работать с ними, если их имена перечислены в файле .ini.
Генератор кода. Генерация кода для такой оболочки, как IBM SanFrancisco, оказалась делом не простым. Первая попытка написать генератор кода оказалась неудачной. Это была программа Java, которая проверяет модель и пишет связанные строки, перемежающие со значениями их атрибутов метамодели, в файл. Многие генераторы кода используют аналогичный подход, обычно применяя в качестве языка сценариев некоторую форму BASIC.
Серверная модель программирования SanFrancisco не очень сложна, но объемна. Клиентский код для управления транзакциями и графический пользовательских интерфейс еще больше усложняют этот код. Для наших экспериментов с архитектурой был необходим значительно более эффективный подход, позволяющий разработать приемлемый генератор кода для SanFrancisco.
Цели генерации кода. Метод самоанализа шаблонов (introspection-template) для генерации кода, который сейчас применяется в Business Component Prototyper, удовлетворяет всем предъявляемым требованиям:
- подход на базе шаблонов, который позволяет изменять программу на Java без перекомпиляции;
- легко читаемые шаблоны, позволяющие разработчику без труда представить, каким будет итоговый код, и дающие пользователям возможность адаптировать код к своим особым требованиям;
- изменения метамодели сразу же появляются в шаблонах;
- генерация кода на Java, а также генерация текста для различных целей, таких как документация HTML, информация о конфигурации SanFrancisco и т.д.;
- добавление новых шаблонов, к примеру, чтобы сгенерировать код для других оболочек. Новый стандарт Enterprise JavaBeans здесь представляет большой интерес.
Самоанализирующиеся шаблоны. BC Prototyper использует для генерации кода самоанализирующиеся шаблоны. Эти шаблоны представляют собой документы XML. Каждый шаблон соответствует генерируемому файлу. Например, модель программирования SanFrancisco предписывает, что для класса AddressBook в модели на Рисунке 2 должны быть сгенерированы три класса Java (в трех файлах .java): AddressBook.java, AddressBookImpl.java и AddressBookFactory.java. Для каждого из этих файлов существует отдельный шаблон. Дополнительные шаблоны указывают код для клиентской реализации.
Можно воспринимать шаблоны и по-другому: рассматривать их как исходный текст, где теги XML или сущности XML (не путать с сущностями SanFrancisco) показывают, как этот исходный текст должен быть изменен, чтобы стать генерируемым кодом.
Единица генерируемого кода определяется с помощью тегов .
Правило, имеющее спецификацию , определяет множество объектов, на которых это правило работает. Это могут быть все классы в модели, все атрибуты класса, все методы класса или все связи класса.
Область действия правила можно ограничить с помощью элемента . К примеру, в правиле на Рисунке 10 рассматриваются только атрибуты типа String, int, float или long.
Наконец, правило может содержать исходный код прототипов и сущности XML в исходном коде. Сущности XML разделяются символами «&» и «;». К примеру, выражение «&type;» в правиле будет заменено на реальный тип атрибута. Во время генерации кода эти сущности XML заменяются значениями, которые находятся с помощью самоанализа в модели.
Это звучит довольно абстрактно и необходим конкретный пример. Посмотрим на множество правил в модели программирования SanFrancisco, которая определяет, как реализовать операцию «get access» для примитива или атрибутов String и классов Dependent, с которыми поддерживаются связи один-к-одному. На Рисунке 9 показана упрощенная форма правил.
Рис. 9. Упрощенное правило генерации кода SanFrancisco |
Преобразование правил не столь уж просто, поскольку способ, которым SanFrancisco определяет правила генерации в модели программирования, отображается на метамодель BC Prototyper отнюдь не напрямую. Шаблон BC Prototyper показан на Рисунке 10.
Рис. 10. Фрагмент самоанализирующегося шаблона |
Сущности XML требуют специальной обработки и мы не уверены, может ли это быть сделано в соответствии со стандартом XML [7]. Причина в том, что если мы используем сущности XML, разобранные с помощью синтаксического анализа, DTD (определение типа данных) должны меняться во время обработки и адаптироваться к текущим значениям в модели.
Самоанализирующийся шаблон имеет тесную связь со структурой метамодели. Имена сущностей XML соответствуют именам атрибутов классов в метамодели. Во время обработки шаблона сущности XML меняются на значения соответствующих атрибутов.
За счет использования самоанализирующихся шаблонов, скорость разработки генератора кода полностью определяется готовностью приемлемых кодов примеров. Можно было за короткое время разработать генератор кода, который генерирует код с функциональностью почти сравнимой со стандартным генератором кода SanFrancisco. Кроме того, BC Prototyper полностью генерирует клиентский код и графический пользовательский интерфейс. Этот клиентский код выполняет управление транзакциями и реализуют службы, подходящие для задач управления на бизнес-объектах, а также включает в себя графический пользовательский интерфейс. Кроме того, создаются некоторые полезные файлы .bat и генерируются файлы, содержащие информацию об именах и т.д.
Качество и производительность генерируемого приложения, конечно, полностью определяется содержанием шаблонов. Поскольку шаблоны также легко изменить, мы также могли генерировать кода лучшего качества.
Использование компонентов в BC Prototyper
Любой инструментарий разработки, который поддерживает оболочку, такую как IBM SanFrancisco, должен иметь стратегию поддержки компонентов. При моделировании в Rational Rose, разработчику просто необходима полная модель SanFrancisco и модели нового приложения на ее основе. Для BC Prototyper подобный подход не казался столь уж превосходным. В таком случае могли бы использоваться только компоненты, для которых имеется модель UML. Для оболочки SanFrancisco это верно, но применение подобного подхода сделало бы BC Prototyper неустойчивым и немасштабируемым.
Еще одна возможность - использовать импортер исходного кода в BC Prototyper. Мы анализировали такой подход применительно к реинженирингу компонентов из исходных файлов. Основной его недостаток состоит в том, что исходные тексты имеются далеко не всегда.
Решение, выбранное для BC Prototyper, состояло в том, чтобы импортировать информацию из файлов .class. Это очень общее решение и может применяться к любому скомпилированному файлу Java. Для SanFrancisco некоторые шаблоны модели программирования применяются в процессе реинжениринга. Было обнаружено, что некоторую информацию полностью извлечь невозможно. Область применения многих инструментальных средств SanFrancisco может быть значительно расширена, если бы можно было создавать и инициализировать информацию, к примеру, с помощью статической переменной для каждого компонента.
Вспомогательный процесс, который может быть выполнен в пакетном режиме, создает компоненты в формате BC Prototyper из файлов .class, и помещает их в каталог. Каталог - это простая файловая структура, которая соответствует структуре пакетов импортированных файлов классов.
Рис. 11. Сгенерированный графический пользовательский интерфейс для общеупотребительного бизнес-объекта SanFrancisco |
Как только компонент попадает в рабочую область BC Prototyper, он может быть использован также, как любой класс, определенный пользователем. Содержимое серверной части не должно меняться, но может быть изменена спецификация представления.
На Рисунке 11 показан результат исполнения кода, сгенерированного из спецификации представления по умолчанию в компоненте Address - одного из общеупотребительных бизнес-объектов SanFrancisco.
BC Prototyper будет генерировать приемлемый клиентский код для доступа к компонентным объектам с сервера. Он также будет обрабатывать объединения или другие связи, установленные в модели.
Еще один пример
В качестве последнего примера мы решили привести приложение, которое не только определяет некоторые объекты данных и генерирует интерфейс обслуживания. В своей книге Object Lessons [8] Том Лав описывает простую игру в кости, называемую Greed. Правила этой игры таковы.
- Каждый игрок бросает пять костей, по очереди, до тех пор, пока какой-нибудь игрок не набрал более 5000 очков и все игроки сделали равное количество бросков. (Каждая кость имеет шесть граней; каждая грань содержит уникальное значение от одного до шести).
- Правила подсчета очков следующие: Три одинаковых - 100, умноженное на значение одной из этих трех костей; три единицы - 1000 очков; одна единица - 100 очков; одна пятерка - 50 очков;
- Кость, которая не увеличивает число очков во время броска может быть кинута еще раз.
- Если все кости во время броска дают очки, их все можно кинуть еще раз.
- Если ни одна кость не дает очков во время броска, игрок объявляется «банкротом» за этот ход (ход заканчивается без очков).
Книга Лава описывает выигрышную тактику для реализации этой игры, где решение запрограммировано на C++, Object Pascal, Smalltalk, Eiffel и др. В решениях, представленных в книге, игра ведется на одной рабочей станции. В нашем случае каждый из игроков может иметь собственную рабочую станцию и играть с другими пользователями по сети. SanFrancisco со своими функциями уведомления, предлагает хорошую платформу для реализации данной игры.
Игра Greed имеет несколько игроков и только один «стаканчик для костей» (Cup). В стаканчике находится несколько костей (в нашем случае - пять) и игрок получает стаканчик на время хода. В Таблице 2 приводится краткое описание методов и назначения каждого класса.
В разрабатываемой нами распределенной версии игры стоит отметить методы identifyPlayer( ) и businessObjectChanged( ). На сервере размещен один постоянный экземпляр GreedGame. Когда состояния этого объекта меняется, все игроки получают уведомления через службу уведомлений SanFrancisco. Сообщение businessObjectChanged посылается игроком, когда игрок как-то меняет состояние этого постоянного объекта. Чтобы присоединиться к игре удаленный клиент создает объект Player и добавляет его к множеству игроков в объекте GreedGame. Клиент содержит локальную часть объекта Player. Игрок использует identifyPlayer, чтобы получить имя текущего игрока из объекта GreedGame. Сравнивая это имя с именем игрока на клиенте, игрок знает, когда наступает его ход.
Отметим также, что постоянный экземпляр GreedGame позволяет игрокам временно прервать игру, а на следующий день вернуться и продолжить.
Графический пользовательских интерфейс игры содержит сгенерированный код, хотя ясно, что придется писать некоторую программу, чтобы показать кость графически. Каждый игрок будет извещаться об изменениях в игре и сможет увидеть в реальном времени, какие значения выпали на гранях кубика, а также кто именно сейчас играет (см. Рисунок 12).
Рис. 12. Игра Greed так, как ее видит игрок Ben Winner |
В отличие от примера с адресной книгой, в игре Greed не использованы общеупотребительные бизнес-объекты SanFrancisco.
Заключение
Business Component Prototyper - инструментальное средство, которое само по себе представляет прототип, демонстрирующий новые возможности инструментария разработки для сред Java.
Основная часть инструментария разрабатывается с помощью самого инструментария. Применение генерации кода позволяет быстро обновить метаинформацию, используемую в инструментарии и его пользовательском интерфейсе.
BC Prototyper имеет гибкий, удобный в обслуживании и настраиваемый генератор кода, который позволяет намного быстрее вести более мощную генерацию кода.
BC Prototyper поддерживает компоненты, в частности, компоненты SanFrancisco, как своего рода «черные ящики». Благодаря чему инструментарий сохраняет небольшой размер и способен обрабатывать очень большие модели, такие как модель SanFrancisco.
Благодарности
В первую очередь хотелось бы поблагодарить Питера ван Эмде Боаса и Маартена ван Ноухьюса, которые оказали мне большую помощь и поддержку на первых этапах этого проекта. Что касается разработки Business Component Prototyper, я хотел бы поблагодарить Дэвида Вейлерса, студента, который создал первоначальную структуру подключаемых адаптеров и импортер исходных текстов Java; Джеффа Райана, который руководил проектом и очень много сделал для реализации связанных с утилитами SanFrancisco функций; Чару Пури, который работал над пользовательским интерфейсом и шаблонами для генерации кода; Боба Шмидта, который всем этим руководил; Джулиуса Питера, который поддержал идею проекта, и, последним - Эдди Блума, сыгравшим далеко не последнюю роль в работе над BC Prototyper и тратившим на него не только свое вечернее время.
Литература
[1] B. J. Cox, Object-Oriented Programming: An Evolutionary Approach, Addison-Wesley Publishing Co., Reading, MA (1987).
[2] D. A. Taylor, Object-Oriented Information Systems: Planning and Implementation, John Wiley & Sons, Inc., New York (1992).
[3] E. Yourdon, Object-Oriented Systems Design: An Integrated Approach, Prentice Hall, Inc., Upper Saddle River, NJ (1994).
[4] UML is the language that resulted from cooperation among well-known object technology methodologists: Grady Booch, James Rumbaugh, and Ivar Jacobson.
[5] The publication of this paper does not imply that IBM will develop tools based on the BC Prototyper architecture. It also does not imply that BC Prototyper will be supported with new versions of SanFrancisco. The version of BC Prototyper described here contains experimental new functionality, such as component support, which is not available in the version provided with SanFrancisco v 1.40. BC Prototyper is intended for evaluation, education, and simple prototyping use. For the development of production applications, other modeling tools should be used.
[6] The oldest (and very successful) multinational corporation in history was the VOC (United Company for the East Indies), a trading company that existed from 1602 to 1799. In 1618, the VOC sent the ship УNieuw-Hoorn,Ф with Willem IJsbrandz (УIJФ is the Dutch way to write УYФ) Bontekoe as captain, on a voyage to Batavia (now Jakarta) on the island of Java to trade silver for spices, tea, and coffee. Near the end of the voyage the ship explodedЧthe brandy caught fire and lit the gunpowder. Captain Bontekoe was saved and led about 70 men, in a small boat with sails made of clothing and almost no food or water, navigating by the stars, safely ashore. He wrote a book about this trip, which is still, 350 years later, the most famous travel adventure book in Holland.
[7] W3C, Extensible Markup Language (XML) 1.0, http://www.w3.org/TR/1998/REC-xml-19980210.
[8] T. Love, Object Lessons: Lessons Learned in Object-Oriented Development Projects, SIGS Books, Inc., New York (1993).
Метка GUI | Описание | Атрибут |
Description | Назначение этого экземпляра атрибута | comment |
Attribute name | Имя атрибута | name |
Scope | Сфера действия атрибута | scope |
Data type | Тип атрибута - по умолчанию String. Кроме того, видимыми являются атрибуты String, char, Boolean, int, byte, short, long, float и double. | type |
Attribute label | Имя, используемое как метка для текстового поля и т.д. | labelName |
View type | Определяет, каким образом атрибут будет представлен в графическом пользовательском интерфейсе - по умолчанию TextField. Также поддерживаются TextArea, Choice и Checkbox. Если указан тип Choice, строки выводятся как возможности выбора, которые должны быть доступны в viewInfo | viewType |
View information | Содержит более подробную информации о том, каким должно быть представление. Здесь могут быть указаны строки возможностей выбора. | viewInfo |
Constraint | Ограничение на этот атрибут. Это должно быть корректное выражение Java, имеющее значение «истина» или «ложь». | constraint |
Constraint exception message | Исключение, возникающее, когда значения constraint «ложь» | constraintMessage |
This is the key attribute of thisobject | Показывает, является ли данный атрибут ключевым атрибутом объекта | isKey |
Initial value | Значение, присваиваемое атрибуту при создании объекта. Оно должно быть корректным выражением Java. | initialValue |
Tab group | Имя группы для данного атрибута. Текстовые поля с одним и тем же именем группы отображаются на панели с вкладками, где имя группы - это текст на вкладке. | tabGroup |
Key sequence number | Если данный атрибут - ключевой, то номер показывает порядок значений ключа. Все ключевые атрибуты вместе должны указывать уникальное значение в наборе объектов этого класса. | keySeqNo |
Is read-only | Указывает, относится ли данный атрибут к атрибутам только для чтения | readOnly |
Multiplicity | Позволяет атрибуту быть набором или массивом атрибутов примитивного типа | referenceBy |
CG directives | Директивы генерации кода | cgDirectives |
Framework type | Поддерживается для атрибутов типа, относящегося к подклассам Entity, Dependent или Command; к примеру, DCurrencyValue (подкласс Dependent). Это позволяет избежать необходимости создавать их как реальные классы. | frameworkType |
Корпорация IBM, все права защищены, 2000. Перевод публикуется с разрешения IBM. van Emde Boas-Lubsen, Business Component Prototyper for SanFrancisco: An experiment in architecture for application development tools. IBM Systems Journal. No. 2, Vol. 39, 2000 - SanFrancisco: Tools, Components, and Applications