"", 6, 2008 .

УДК 519.688
Егоров Я.С.

РЕШЕНИЕ ЗАДАЧ ПРОЕКТИРОВАНИЯ СТРУКТУРЫ ДАННЫХ И БИЗНЕС-ЛОГИКИ С ИСПОЛЬЗОВАНИЕМ ШАБЛОНОВ ПРОЕКТИРОВАНИЯ

 

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

Шаблоны проектирования
Опыт создания множества бизнес-приложений разными независимыми разработчиками позволил собрать коллекцию шаблонов проектирования (Design Patterns) – методов и алгоритмов решения стандартных, часто встречающихся задач при проектировании и разработке сложных программных комплексов.
Общепризнанная коллекция базовых шаблонов проектирования была собрана в 1995 году. С тех пор появилось множество новых специальных шаблонов, а также реализаций классических шаблонов с помощью различных технологий в прикладных областях.
Классические шаблоны проектирования делятся на три основные группы:

Существуют различные платформы и способы технической реализации приведенной модели. В данной статье рассматриваются примеры реализации шаблонов на Java 2 Enterprise Edition (J2EE). Технология позволяет реализовывать компоненты системы при помощи компонентов Enterprise Java Beans (EJB).

Порождающие шаблоны
Порождающие шаблоны проектирования используются в процессе создания экземпляров объектов и помогают сделать систему независимой от способа создания, композиции и представления объектов. Шаблон, порождающий классы, использует наследование для изменения класса-определения, а шаблон, порождающий объекты, делегирует создание экземпляра другому объекту. Эти шаблоны оказываются важны, когда система больше зависит от композиции объектов, чем от наследования классов.
Порождающие шаблоны используются для решения двух основных задач. Во-первых, они инкапсулируют знания о конкретных классах, которые применяются в системе. Во-вторых, скрывают детали того, как эти классы создаются и стыкуются. Единственная информация об объектах, известная системе, — это их интерфейсы, определенные с помощью абстрактных классов.

Структурные шаблоны
Структурные шаблоны задают организацию классов и объектов. Эти шаблоны рассматривают, как классы наследуют друг другу или как они составляются из других классов.
На сегодняшний день разработано множество шаблонов проектирования программного обеспечения, описывающих методы решения тех или иных задач при построении приложения. Применяя шаблоны, можно использовать общий подход к решению задачи, выполняя конкретную реализацию в рамках определенной предметной области и используемых технологий.
 Основная концепция шаблона может быть рассмотрена, как основная концепция дизайна программы: добавление уровня абстракции.    Таким образом, цель шаблонов проектирования состоит в изоляции изменений в коде. Рассмотрим набор шаблонов для реализации управления доступом к информации и передачи данных между компонентами приложения:

 

Шаблоны поведения
Шаблоны поведения задают способ взаимодействия объектов друг с другом. Они помогают сделать сложное поведение управляемым путем задания ответственностей объектов и способов их связи друг с другом.
            Шаблоны поведения позволяют решать такие задачи как делегирование команд обработчикам объектов, инкапсулирование операций и параметров в служебных объектах, запоминание состояния объекта с возможностью его восстановления и другие задачи  динамического поведения приложения.

Шаблон Data Access Object
При работе любой информационной системы возникает необходимость обмениваться информацией с неким хранилищем данных, т.е. получать и сохранять данные. В современных информационных системах используются различные форматы хранения данных. Существует множество баз данных, каждая из которых требует реализации особых методов доступа к данным. При разработке информационной системы актуальна задача абстракции от данных системы от конкретной структуры данных.
Абстракция данных необходима для того, чтобы приложение могло работать с разными базами данных. Такой подход важен при масштабировании системы, при которой может возникнуть необходимость миграции на другую базу данных без потери информации.
В связи с этим возникают следующие проблемы:

Перечисленные проблемы могут быть решены при помощи Data Access Object (DAO). DAO служит для абстрагирования и инкапсуляции доступа к хранилищу данных. Объект DAO служит переходником между приложением и БД и реализует механизм доступа и обмена данными с БД.
Объект DAO реализует все прямые операции с хранилищем данных, например SQL-запросы к БД. Бизнес-объекты никогда не обращаются напрямую к БД, они не содержат информации о типе хранилища данных и интерфейсах связи с ним. При необходимости получения или передачи информации бизнес-объект вызывает определенный метод класса DAO, который выполняет проекцию бизнес-структуры на физическую структуру данных и выполняет необходимые запросы к БД, исходя из конкретной реализации и имеющихся интерфейсов.
Как правило, DAO используется в совокупности с другим шаблоном – Value Object для передачи объекта между клиентом и сервером.

Рис. 1. Диаграмма классов шаблона Data Access Object.

Использование дополнительного уровня абстракции данных позволяет решить следующие проблемы:

Шаблон Value Object
            При использовании архитектуры клиент-сервер сложные системы передают через сеть большой объем данных. Становится актуальной задача оптимизация механизма обмена данными между клиентом и сервером и уменьшения загрузки сети. Такое требование может быть вызвано как техническими, так и экономическими причинами, например, ограниченной проходимостью Интернет-канала или стоимостью трафика.
            Целью шаблона Value Object (VO), является решение следующих проблем передачи данных между клиентом и сервером:

Шаблон предполагает использование объекта Value Object для инкапсуляции и передачи информации. Объект VO может быть отослан и вызван при помощи одного метода. Когда клиенту необходимо вызвать атрибут бизнес-объекта, создается производный от него объект VO, который передается на клиент полностью. Фактически, на клиенте создается временная копия объекта. Далее клиент работает с этой копией, которая по завершении работы возвращается на сервер. Таким образом, множество обращений клиента к атрибутам бизнес-объекта на сервере заменяется одним вызовом объекта VO.

Рис. 2. Диаграмма деятельности шаблона Value Object.
           
            Использование шаблона Value Object позволяет упростить компонент-сущность EJB, реализующий бизнес объект. Вместо реализации множества обращений достаточно реализовать одно обращение к объекту VO. Реализация шаблона помогает уменьшить общий объем данных, передаваемых по сети и уменьшить вероятность проблем, связанных с некачественным соединением.

Шаблон Generic Attributes Access
            Использование комбинации шаблонов Data Access Object и Value Object – один из наиболее распространенных способов решения задачи передачи крупных объемов данных. Однако он имеет ряд существенных недостатков. Основной из них – сложность реализации и поддержки, обусловленная необходимостью корректной обработки транзакций и синхронизацией объектов.
            Другая проблема – недостаточная масштабируемость. Объект VO эффективен для небольших по размеру компонентов. Если же компонент моделирует сложный объект с большим количеством атрибутов (например, пакет акций с сотнями атрибутов), реализация его в виде EJB потребует написания множества методов для обработки атрибутов, что выльется в весьма трудоемкую задачу.
            Шаблон Generic Attributes Access предполагает решение той же задачи с использованием контейнера HashMap. Доступ к атрибутам бизнес-объекта абстрагируется при помощи общего интерфейса Attribute Access, который использует структуру HashMap для передачи атрибутов в бизнес-объект и обратно в форме ключ-значение.

Рис. 3. Диаграмма деятельности шаблона Generic Attributes Access.

 

Шаблон Command
При сообщении между двумя объектами один из объектов часто посылает команду другому, приказывающую выполнить определенное действие. Наиболее распространенный способ реализации такой ситуации: первый объект («создатель запроса») хранит ссылку на второй объект («получатель»). Чтобы послать команду, создатель запроса вызывает определенный метод получателя.
Однако бывают случаи, когда создатель запроса не располагает информацией о получателе или ему все равно, кто получит команду. То есть, создатель запроса хочет послать команду абстрактно неопределенному получателю.
Шаблон проектирования Command инкапсулирует понятие команды в объекте. Создатель запроса хранит ссылку на объект «Команда», а не на конкретного получателя. Создатель запроса посылает команду объекту «Команда», вызывая один из его методов. Далее уже объект «Команда» отвечает за обработку команды и переадресацию ее конкретному получателю для исполнения.

Реализация
Рассмотренные в данной статье шаблонны были реализованы в рамках разработки системы дистанционного обучения Competentum.Instructor.
Персистенция данных, т.е. проецирование и сущностей системы на базу данных и их сохранение, реализована с помощью единственного компонента-сущности BaseEJB. Первичный ключ такого компонента – ID, который состоит из ссылки на модель данных и целого числа, уникального на множестве компонентов, ссылающихся на одну и ту же модель.
Каждый тип постоянного объекта Competentum представляется в виде класса-модели – наследника абстрактного класса Model. Класс Model определяет описание структуры данных, необходимое для сохранения объекта в базе данных, генератор ключей для создания уникальных идентификаторов и другие общие принципы моделей данных. Таким образом, класс Model задает общие правила хранения сущностей системы в базе данных. Класс Model подключается к BaseEJB, позволяя совершать операции персистенции над одним из компонентов-сущностей. Это избавляет разработчика от необходимости создавать дополнительные классы поддержки сложных компонентов EJB для каждого типа сохраняемого объекта.
Данные, сохраненные в БД и ассоциирующиеся с реализацией компонента BaseEJB, представляются с помощью объекта Details. Каждая запись таблицы БД ассоциирована с объектом (компонентом-сущностью) BaseEJB. Все данные из колонок хранятся в объекте класса Details, который является переменной класса BaseEJB. Этот класс наследуется из HashMap и в сочетании с классом DataStructure реализует шаблон Generic Attributes Access. Данные, загружаемые в этот шаблон при чтении объекта из базы данных, идентифицируются на основе объекта DataStructure, заданного соответствующей данному объекту моделью. Класс Details также имеет методы для доступа к данным, хранящимся в дополнительных таблицах.
В большинстве случаев разработка нового персистентного объекта сводится к определению единственного класса, наследника Model, и переопределению единственного метода createDataStructure.
Бизнес-логика системы реализована на базе шаблона Command, что позволяет абстрагировать выполнение операций от объектов исполнителей. При этом задается единственный компонент сессии ManagerEJB, не имеющий состояний и способный исполнять классы-действия. Информация о сессии пользователя, включая идентификационные данные, используемые для ограничений полномочий системой безопасности, хранится в компоненте сессии SessionEJB, который в свою очередь имеет состояния.
Каждая операция представляет собой элемент бизнес-логики, доступный для многократного использования. Операция, которую необходимо исполнить в рамках определенной транзакции, представляется в виде наследника абстрактного класса-операции Action и переопределяет родительский метод execute(), задавая в нем необходимую бизнес-логику. Классы Action создаются на стороне клиента и отсылаются для исполнения на сервер компонентом ManagerEJB. Метод execute() предоставляет прямой доступ к каталогу Base, а также к уже существующим операциям. В большинстве случаев Base не может быть доступен, поскольку любое действие над ним совершается при помощи метода операции. Однако он может быть доступен в некоторых исключительных случаях, например, при необходимости повышенной производительности операции.
На приведенной схеме показана UML диаграмма последовательностей вызовов. Она иллюстрирует то, каким образом выполняется бизнес-логика системы.

Рис. 4. Диаграмма деятельности шаблона Command

Заключение
Рассмотренный набор шаблонов позволяет эффективно решать ряд задач, возникающих при построении систем на уровне доступа к данным и уровне бизнес-логики. Шаблоны реализованы с использованием технологии EJB. Результаты исследования применены при разработке системы дистанционного обучения Competentum.Instructor, успешно используемой во многих российских организациях.

Список литературы

 

"", 6, 2008 .