![]() | ||||||||
BOLD - инструмент реализации MDA в Delphi Часть 7. Объектное пространство и OCL. Графический интерфейсИсточник: КомпьютерПресс 11'2003 Константин Грибачев
Borland MDA и Microsoft .NET
Принципиальным отличием версии Architect от ранее вышедших версий продукта Borland C# Builder является присутствие в ней средств разработки MDA-приложений. Из их состава важнейшим элементом является интегрированная в Borland C# Builder Architect технология ECO - Enterprise Core Objects. Читатели, ознакомившиеся с технологией Bold for Delphi, обнаружат в ECO очень много общего с Bold. И это не случайно, поскольку ECO базируется на технологии Bold. С целью полной интеграции MDA-инструментов в среду разработки компания Borland сделала еще один весьма логичный шаг: в состав Borland C# Builder Architect теперь включен полнофункциональный редактор UML-моделей, созданный на базе продуктов TogetherSoft2. Благодаря этому Borland C# Builder Architect стал первым продуктом Borland, обеспечивающим полный жизненный цикл разработки приложений - от создания модели до генерации кода.
Доработка приложения
Для начала, по аналогии со списками авторов и книг, подключим визуальные компоненты BoldGrid5, BoldGrid6 и BoldGrid7 к описателям списков ListAllCountries, ListAllPublishers, ListAllThematics соответственно, то есть будем отображать в этих компонентах списки стран, издательств и тематических направлений книг (рис. 2), для начала создав в них столбцы по умолчанию (то есть столбец «Название»). Для сохранения данных запишем в обработчик события OnClose формы следующий оператор: DataModule1.BoldSystemHandle1.UpdateDatabase; Запустим наше приложение, заполним таблицы со списком авторов, книг, стран, издательств и тематики данными4 и убедимся, что они сохраняются при выходе из приложения. Теперь можно более подробно познакомиться с организацией взаимодействия бизнес-уровня и графического интерфейса.
OCL и графический интерфейс
Обратите внимание, что метка BoldLabel1, как и любой другой визуальный компонент Borland MDA, имеет свойство BoldHandle. Из предыдущей статьи данного цикла нам известно, что в качестве источника данных для этого описателя целесообразно выбрать ListAllAvtors, что мы и сделаем. А в качестве OCL-выражения напишем вручную или введем во встроенном OCL-редакторе (напомним, что OCL-редактор вызывается при двойном щелчке по свойству Expression компонента ListAllAvtors) следующее выражение: «’Страна ‘+strana.nazvanie», где ‘Страна ’ - это текстовая константа, а «strana.nazvanie» - OCL-запрос для выбора страны для текущего автора и выбора атрибута «название» класса «’Страна’ - nazvanie» для отображения его на нашей форме. Как видим, это делается весьма просто. Встроенный в Borland MDA механизм обеспечит при этом автоматическое изменение текста метки при изменении текущего автора в компоненте BoldGrid1. На этом моменте стоит остановиться подробнее - как уже упоминалось ранее, одним из важных механизмов, встроенных в Borland MDA, является механизм так называемой подписки на события (subscribing). Рассмотрим работу данного механизма. В нашем случае, связав свойство BoldHandle метки с описателем списков авторов ListAllAvtors, мы «сообщили» среде Borland MDA, что необходимо «подписать» нашу метку на события, возникающие при любых изменениях списка авторов, в том числе и на события, возникающие при переходах от одного объекта к другому при перемещении по списку авторов. Кроме того, мы сформировали OCL-запрос, который должен быть выполнен при наступлении такого события, с указанием конкретной необходимой нам информации (название страны, где проживает автор). Остальное среда Borland MDA сделает самостоятельно, то есть по наступлению события, связанного с изменениями в списке авторов, проверит, есть ли элементы, подписавшиеся на изменение этого списка, и, если таковые имеются, выполнит соответствующий OCL-запрос, а также вернет полученные данные подписанному элементу для дальнейшего использования (в данном случае - для отображения на форме). Отметим, что в данном случае «подписку» незаметно для нас «оформила» сама среда, но это совсем не обязательно. Разработчик может и самостоятельно «подписать» любой Bold-элемент на необходимое событие, воспользовавшись специальными методами класса TboldElement. Читатель вправе спросить, что же здесь нового. Мы знаем, что при традиционной разработке приложений с базами данных можно использовать визуальный компонент TDBLabel - метку, которая автоматически отслеживает и отображает на форме содержимое указанного поля таблицы БД при перемещении по сетке. Однако в нашем классе «Автор» отсутствует атрибут «Страна» и для решения этой задачи традиционными методами нужно было бы сформировать в общем случае SQL-запрос, который бы выбирал страну из другой таблицы для конкретного автора и связать метку с этим запросом. Кроме того, необходимо было бы специально «подключать» этот запрос к сетке либо к набору данных, чтобы он выполнялся при переходах между авторами. Мы же обошлись без подобных операций. Аналогично проделаем операции по подключению Bold-меток BoldLabel2 (для отображения названия издательства книги) и BoldLabel3 (для отображения тематики книги). В качестве источника информации для этих меток выступает описатель списка книг ListAllBooks. После запуска приложения убеждаемся, что тексты меток отслеживают перемещение по списку книг, отображаемых в компоненте BoldGrid3.
OCL и вычисляемые данные
Аналогично, в компоненте BoldGrid6 добавим столбец для отображения количества книг, изданных конкретным издательством. В этом случае OCL-выражение, как легко убедиться, будет тем же самым, поскольку название роли такое же, что и в предыдущем случае. И наконец, обратимся к компоненту BoldGrid5, отображающему названия стран. До этого момента в нем отображался всего один столбец, созданный по умолчанию и содержащий название страны. Предположим, что мы хотим получить дополнительную статистическую информацию по каждой стране, а именно - общее количество авторов, проживающих в этой стране, общее количество издательств, а также общее количество всех изданных в данной стране книг. Для этого добавим к сетке BoldGrid5 три новых столбца - с названиями «Авт», «Изд», «Книг». Для столбца «Авт» выражение OCL примет следующий вид: «avtory->size.asString», для столбца «Изд»: «izdatel_stva ->size.asString». Однако для последнего столбца подобное простое выражение не будет являться решением, поскольку алгоритм расчета суммарного количества книг оказывается более сложным. В самом деле, в нашей модели отсутствует ассоциация, непосредственно связывающая оба класса - «Страна» и «Книга», и это вовсе не считается недостатком модели, поскольку вся необходимая информация для решения поставленной задачи у нас есть. Алгоритм решения на естественном языке можно сформулировать для данного случая примерно так: для каждой страны необходимо выбрать все ее издательства, получить количество книг, изданных каждым издательством, и просуммировать все полученные величины. На языке OCL данный алгоритм может быть реализован посредством следующего выражения: «izdatel_stva->collect(knigi->size)->sum». Здесь мы впервые сталкиваемся с операторами взятия коллекции «->collect» и оператором суммирования «->sum». Смысл их вполне ясен из рассмотренного примера. Можно сказать, что во многом оператор коллекции схож с известным SQL-оператором группировки «group by». Стоит отметить, что оператор получения коллекции применяется в OCL-выражениях довольно часто. После запуска приложения можно убедиться, что оно приобрело новые, необходимые нам качества (рис. 4). На этом мы завершаем описание основных возможностей OCL. На примере созданного приложения были продемонстрированы основные подходы к реализации взаимодействия бизнес-уровня и графического интерфейса пользователя. Мы убедились на практике, что при использовании Borland MDA эта среда обеспечивает принципиально новые возможности по формированию такого взаимодействия благодаря встроенной поддержке языка OCL. Так, любой визуальный элемент приобретает способность отображать практически любые данные, содержащиеся в объектах объектного пространства. В рассмотренном примере мы «заставили» метки и сетки отображать информацию из объектов, принадлежащих разным классам нашей модели, и даже получать новую информацию, которая непосредственно в модели не содержится (статистические данные по странам, издательствам и т.д.). Необходимо отметить, что формирование такого рода взаимодействий не ограничивается этапом разработки приложения. Любое OCL-выражение можно формировать и присваивать и во время выполнения программы, при этом OCL-запрос будет исполнен средой Borland MDA, поскольку OCL-интерпретатор включается в состав исполняемого exe-файла приложения, так же как и вся информация о модели. Нельзя еще раз не отметить, что при создании приложения мы не писали код на языке Object Pascal, и не использовали язык SQL, но, тем не менее, смогли «завязать» все элементы нашей модели в одно целое. Использование OCL позволяет сделать приложение более платформенно-независимым, так как язык OCL сам является платформенно-независимым языком. На практике это означает, что бизнес-логика приложения, будучи один раз создана на языке OCL без кодирования на языках программирования, при переносе разработки на другую платформу полностью сохранится и может быть повторно использована. И это является еще одним преимуществом технологии Borland MDA.
OCL и вычисляемые атрибуты
|