- •Оглавление
- •Предисловие
- •Введение
- •Часть I Обзор Глава 1 "Расслоение" системы
- •Развитие модели слоев в корпоративных программных приложениях
- •Три основных слоя
- •Где должны функционировать слои
- •Глава 2 Организация бизнес-логики
- •Выбор типового решения
- •Глава 3 Объектные модели и реляционные базы данных
- •Архитектурные решения
- •Функциональные проблемы
- •Считывание данных
- •Взаимное отображение объектов и реляционных структур
- •Отображение связей
- •Наследование
- •Реализация отображения
- •Двойное отображение
- •Использование метаданных
- •Соединение с базой данных
- •Другие проблемы
- •Дополнительные источники информации
- •Глава 4 Представление данных в Web
- •Типовые решения представлений
- •Типовые решения входных контроллеров
- •Дополнительные источники информации
- •Глава 5 Управление параллельными заданиями
- •Проблемы параллелизма
- •Контексты выполнения
- •Изолированность и устойчивость данных
- •Стратегии блокирования
- •Предотвращение возможности несогласованного чтения данных
- •Разрешение взаимоблокировок
- •Транзакции
- •Типовые решения задачи обеспечения автономного параллелизма
- •Параллельные операции и серверы приложений
- •Дополнительные источники информации
- •Глава 6 Сеансы и состояния
- •В чем преимущество отсутствия "состояния"
- •Состояние сеанса
- •Глава 7 Стратегии распределенных вычислений
- •Соблазны модели распределенных объектов
- •Интерфейсы локального и удаленного вызова
- •Когда без распределения не обойтись
- •Сужение границ распределения
- •Интерфейсы распределения
- •Глава 8 Общая картина
- •Предметная область
- •Источник данных
- •Платформы и инструменты
- •Другие модели слоев
- •Часть II Типовые решения Глава 9 Представление бизнес-логики Сценарий транзакции (Transaction Script)
- •Модель предметной области (Domain Model)
- •Модуль таблицы (Table Module)
- •Слой служб (Service Layer)
- •Глава 10 Архитектурные типовые решения источников данных Шлюз таблицы данных (Table Data Gateway)
- •Шлюз записи данных (Row Data Gateway)
- •Активная запись (Active Record)
- •Преобразователь данных (Data Mapper)
- •Глава 11 Объектно-реляционные типовые решения, предназначенные для моделирования поведения Единица работы (Unit of Work)
- •Коллекция объектов (Identity Map)
- •Загрузка по требованию (Lazy Load)
- •Глава 12 Объектно-реляционные типовые решения, предназначенные для моделирования структуры Поле идентификации (Identity Field)
- •Отображение внешних ключей (Foreign Key Mapping)
- •Отображение с помощью таблицы ассоциаций (Association Table Mapping)
- •Отображение зависимых объектов (Dependent Mapping)
- •Внедренное значение (Embedded Value)
- •Сериализованный крупный объект (Serialized lob)
- •Наследование с одной таблицей (Single Table Inheritance)
- •Наследование с таблицами для каждого класса (Class Table Inheritance)
- •Наследование с таблицами для каждого конкретного класса (Concrete Table Inheritance)
- •Преобразователи наследования (Inheritance Mappers)
- •Глава 13 Типовые решения объектно-реляционного отображения с использованием метаданных Отображение метаданных (Metadata Mapping)
- •Объект запроса (Query Object)
- •Хранилище (Repository)
- •Глава 14 Типовые решения, предназначенные для представления данных в Web Модель-представление-контроллер (Model View Controller)
- •Контроллер страниц (Page Controller)
- •Контроллер запросов (Front Controller)
- •Представление по шаблону (Template View)
- •Представление с преобразованием (Transform View)
- •Двухэтапное представление (Two Step View)
- •Контроллер приложения (Application Controller)
- •Глава 15 Типовые решения распределенной обработки данных Интерфейс удаленного доступа (Remote Facade)
- •Объект переноса данных (Data Transfer Object)
- •Глава 16 Типовые решения для обработки задач автономного параллелизма Оптимистическая автономная блокировка (Optimistic Offline Lock)
- •Пессимистическая автономная блокировка (Pessimistic Offline Lock)
- •Блокировка с низкой степенью детализации (Coarse-Grained Lock)
- •Неявная блокировка (Implicit Lock)
- •Глава 17 Типовые решения для хранения состояния сеанса Сохранение состояния сеанса на стороне клиента (Client Session State)
- •Сохранение состояния сеанса на стороне сервера (Server Session State)
- •Сохранение состояния сеанса в базе данных (Database Session State)
- •Глава 18 Базовые типовые решения Шлюз (Gateway)
- •Преобразователь (Mapper)
- •Супертип слоя (Layer Supertype)
- •Отделенный интерфейс (Separated Interface)
- •Реестр (Registry)
- •Объект-значение (Value Object)
- •Деньги (Money)
- •Частный случай (Special Case)
- •Дополнительный модуль (Plugin)
- •Фиктивная служба (Service Stub)
- •Множество записей (Record Set)
- •Список типовых решений
- •Шпаргалка
- •Как управлять сложным потоком функций приложения?
- •Как взаимодействовать с базой данных?
- •Как избежать загрузки в оперативную память всего содержимого базы данных?
- •Как сохранить структуры наследования в реляционной базе данных?
Преобразователь (Mapper)
Объект, устанавливающий взаимодействие между двумя независимыми объектами
Иногда разработчику необходимо установить взаимодействие между двумя подсистемами, которые не должны знать о существовании друг друга. Чаще всего это происходит, если подсистемы не могут быть изменены или же их не следует связывать зависимостями (напрямую или даже опосредованно через некоторый отдельный элемент).
Принцип действия
Типовое решение преобразователь представляет собой некий "изоляционный" слой, проложенный между двумя подсистемами. Он управляет взаимодействием подсистем, причем ни одна из них об этом даже не догадывается.
Зачастую преобразователь перемещает данные из одного слоя в другой. После активизации преобразователя понять принцип его работы совсем несложно. Самый непростой аспект использования преобразователя — это его запуск, поскольку преобразователь не может быть напрямую вызван одной из подсистем, которые он отображает друг на друга. Иногда управление отображением, а значит, и вызов преобразователя возлагают на некоторую третью подсистему. Вместо этого преобразователь можно реализовать в виде типового решения обозреватель (Observer) [20], выполняющего роль "наблюдателя" за одной из обслуживаемых систем. В этом случае преобразователь активизируется при перехвате событий, сгенерированных этой системой.
Принцип работы преобразователя зависит от природы отображаемых слоев. Наиболее распространенной разновидностью преобразователя является рассмотренный нами ранее преобразователь данных (Data Mapper), примеры использования которого можно найти в главе 10 этой книги.
Назначение
Основное назначение преобразователя состоит в отделении друг от друга различных частей программной системы. Похожие функции выполняет и шлюз (Gateway). Последний применяется гораздо чаще, чем преобразователь, поскольку он намного проще и в написании, и в последующем использовании.
Таким образом, преобразователь необходимо использовать только тогда, когда ни одна из отображаемых систем не должна зависеть от взаимодействия с другой системой. Это действительно важно только в том случае, когда структура взаимодействия особенно сложна и практически не связана с основным назначением каждой системы. Поэтому в корпоративных приложениях главной областью применения преобразователя является обслуживание взаимодействий с базой данных. Соответствующая разновидность преобразователя получила название преобразователя данных.
Концепция преобразователя имеет немало общего с типовым решением медиатор (Mediator) [20] в том плане, что оба они применяются для разделения независимых объектов. Тем не менее между данными типовыми решениями есть принципиальное различие. Объекты, использующие медиатор, знают о его наличии, даже если им неизвестно о существовании друг друга. В свою очередь, объекты, разделенные преобразователем, не знают о наличии последнего.
Супертип слоя (Layer Supertype)
Тип, выполняющий роль суперкласса для всех классов своего слоя
Довольно часто одни и те же методы дублируются во всех объектах слоя. Чтобы избежать повторений, все общее поведение можно вынести в супертип слоя.
Принцип действия
Концепция супертипа слоя, а следовательно, и само типовое решение крайне просты. Все, что от вас требуется, — это создать суперкласс для всех объектов слоя (например, класс DomainObject, являющийся суперклассом для всех объектов домена в модели предметной области (Domain Model). После этого в созданный суперкласс может быть вынесено все общее поведение наподобие сохранения и обработки полей идентификации (Identity Field). Точно так же все преобразователи данных (Data Mapper), образующие слой отображения, могут иметь общий суперкласс, работающий с суперклассом объектов домена.
Если в рассматриваемом слое приложения находятся объекты нескольких различных типов, может понадобиться создать несколько супертипов слоя.
Назначение
Супертип слоя используется тогда, когда все объекты соответствующего слоя имеют некоторые общие свойства или поведение. Поскольку в моих приложениях объекты слоев имеют множество общих черт, применение супертипа слоя вошло у меня в привычку.
Пример: объект домена (Java)
Ниже приведен простенький суперкласс объектов домена, выполняющий обработку их идентификаторов.
class DomainObject...
private Long ID;
public Long getID() {
return ID;
}
public void setID(Long ID) {
Assert.notNull("Cannot set a null ID", ID);
this.ID = ID;
}
public DomainObject(Long ID) {
this.ID = ID;
}
public DomainObject() {
}
