Абстрактная фабрика (Abstract Factory, Factory), др. название Инструментарий (Kit) - GoF
Проблема | Создать семейство взаимосвязанных или взаимозависимых обьектов (не специфицируя их конкретных классов). |
Решение | Создать абстрактный класс, в котором объявлен интерфейс для создания конкретных классов. |
Пример | Какой класс должен отвечать за создание обьектов - адаптеров при использовании паттерна "Адаптер", см. . Если подобные объекты создаются неким объектом уровня предметной области, то будет нарушен принцип разделения обязанностей. |
Преимущества | Изолирует конкретные классы. Поскольку "Абстрактная фабрика" инкапсулирует ответственность за создание классов и сам процесс их создания, то она изолирует клиента от деталей реализации классов. Упрощена замена "Абстрактной фабрики", поскольку она используется в приложении только один раз при инстанцировании. |
Недостатки | Интерфейс "Абстрактной фабрики" фиксирует набор обьектов, которые можно создать. Расширение "Абстрактной фабрики" для изготовления новых обьектов часто затруднительно. |
Адаптер (Adapter) - GoF
Проблема | Необходимо обеспечить взаимодействие несовместимых интерфейсов или как создать единый устойчивый интерфейс для нескольких компонентов с разными интерфейсами. |
Решение | Конвертировать исходный интерфейс компонента к другому виду с помощью промежуточного объекта - адаптера, то есть, добавить специальный объект с общим интерфейсом в рамках данного приложения и перенаправить связи от внешних обьектов к этому объекту - адаптеру. |
Пример | Соответствует примеру из описания паттерна "Полиморфизм", см. п. . |
Активная запись (Active Record)
Описание | Если предметная область несложная, то логично возложить на каждый класс порцию бизнес - логики.
При использовании этого паттерна объект класса "осведомлен" о том, как взаимодействовать с таблицами базы данных. |
АРХИТЕКТУРНЫЕ СИСТЕМНЫЕ ПАТТЕРНЫ
Согласно предложенному принципу классификации паттерны проектирования архитектурные системные паттерны объединены в группы в соответствии с теми задачами, для решения которых они разработаны. Для организации классов или обьектов системы в базовые подструктуры (то есть в подсистемы - соответствующее определение дано в разделе 7.1) используются структурные архитектурные паттерны, см. . С другой стороны, для обеспечения требуемого системного функционала первостепенное значение имеет адекватная организация взаимодействия отдельных архитектурных элементов системы - этой цели служат управления, см. .
В свою очередь, паттерны управления разделены на паттерны централизованного управления, 4.2.1 (то есть паттерны, в которых одна из подсистем полностью отвечает за управление, запускает и завершает работу остальных подсистем) и паттерны управления, подразумевающие децентрализованное реагирование на события, 4.2.2, (согласно этим паттернам на внешние события, определённые в разделе 7.3, отвечает соответствующая подсистема.). Также следует упомянуть, что поскольку проектирование взаимодействия той или иной подсистемы с реляционной базой данных (определенной в разделе 7.3) является неотъемлемой частью разработки корпоративных информационных систем, среди паттернов управления выделена большая группа паттернов, описывающих организацию связи с базой данных, см. .
Цепочка обязанностей (Chain of Responsibility) - GoF
Проблема | Запрос должен быть обработан несколькими объектами. | |
Рекомендации | Логично использовать данный паттерн, если имеется более одного объекта, способного обработать запрос и обработчик заранее неизвестен (и должен быть найден автоматически) или если весь набор обьектов, которые способны обработать запрос, должен задаваться автоматически. | |
Решение | Связать объекты - получатели запроса в цепочку и передать запрос вдоль этой цепочки, пока он не будет обработан. "Обработчик" определяет интерфейс для обработки запросов, и, возможно, реализует связь с преемником, "КонкретныйОбработчик" обрабатывает запрос, за который отвечает, имеет доступ к своему преемнику ("КонкретныйОбработчик" направляет запрос к своему преемнику, если не может обработать запрос сам. | |
Преимущества | Ослабляется связанность (объект не обязан "знать", кто именно обработает его запрос). | |
Недостатки | Нет гарантий, что запрос будет обработан, поскольку он не имеет явного получателя. |
Cохранение сеанса на стороне клиента (Client Session State)
Задача | Сохранить сведения о сеансе, определение - см. п. . |
Решение | Данные о состоянии сеанса можно сохранять на стороне клиента. При этом клиент передает серверу все сведения о сеансе вместе с каждым запросом. Никаких данных о состоянии сеанса на сервере не хранится. Если есть необходимость хранения числового идентификатора сеанса, то альтернативы данному паттерну не существует. |
Преимущества | Можно использовать серверные объекты без состояний, что обеспечивает большую степень отказоустойчивости. |
Недостатки | Возникают проблемы безопасности при передаче данных от клиента серверу - передаваемые данные приходится шифровать. Затруднительно использовать данный паттерн при большом объеме информации о сеансе. Часто возникает проблема преобразования формата данных. |
Cохранение сеанса на стороне сервера (Server Session State)
Задача | Сохранять сведения о сеансе. |
Решение | На клиенте хранится только идентификатор сеанса, а все данные о сеансе хранятся сервером. Для хранения обьектов сеансов на сервере формируется специальная коллекция. |
Преимущества | Передается только идентификатор сеанса, а не весь обьем данных о сеансе. |
Недостатки | Требуются значительные ресурсы сервера. |
Декоратор (Decorator) или Оболочка (Wrapper) - GoF
Проблема | Возложить дополнительные обязанности (прозрачные для клиентов) на отдельный объект, а не на класс в целом. | |
Рекомендации | Применение нескольких "Декораторов" к одному "Компоненту" позволяет произвольным образом сочетать обязанности, например, одно свойство можно добавить дважды. | |
Решение | Динамически добавить объекту новые обязанности не прибегая при этом к порождению подклассов (наследованию). "Компонент"определяет интерфейс для обьектов, на которые могут быть динамически возложены дополнительные обязанности, "КонкретныйКомпонент" определяет объект, на который возлагаются дополнительные обязанности, "Декоратор" - хранит ссылку на объект "Компонент" и определяет интерфейс, соответствующий интерфейсу "Компонента". "КонкретныйДекоратор" возлагает дополнительные обязанности на компонент. "Декоратор" переадресует запросы объекту "Компонент". | |
Преимущества | Большая гибкость, чем у статического наследования: можно добавлять и удалять обязанности во время выполнения программы в то время как при использовании наследования надо было бы создавать новый класс для каждой дополнительной обязанности. Данный паттерн позволяет избежать перегруженных методами классов на верхних уровнях иерархии - новые обязанности можно добавлять по мере необходимости. | |
Недостатки | "Декоратор" и его "Компонент" не идентичны, и, кроме того, получается что система состоит из большого числа мелких обьектов, которые похожи друг на друга и различаются только способом взаимосвязи а не классом и не значениями своих внутренних переменных - такая система сложна в изучении и отладке. |
Диспетчер
Описание | Один системный компонент назначается диспетчером и управляет запуском и завершением других процессов системы и координирует эти процессы. Процессы могут протекать параллельно. |
Рекомендации | Применяется в системах, в которых необходимо организовать параллельные процессы, но может использоваться также и для последовательных систем, в которых- управляющая программа вызывает отдельные подсистемы в зависимости от значений некоторых переменных состояния. |
Пример | Можно использовать в системах реального времени, где нет чересчур строгих временных ограничений (в так называемых "мягких" системах реального времени). |
Единица работы (Unit Of Work)
Задача | При выполнении операций считывания или изменения обьектов система должна гарантировать, что состояние базы данных останется согласованным. Например, на результат загрузки данных не должны влиять изменения, вносимые другими процессами. | |
Решение | Создается специальный объект, "отслеживающий" изменения, вносимые в базу данных. Данное типовое решение позволяет проконтролировать, какие объекты считываются и какие модифицируются и обслужить операции обновления содержимого базы данных. | |
Преимущества | Нет необходимости явно вызывать методы сохранения, достаточно сообщить объекту Единица работы о необходимости фиксации (commit) результатов в базе данных. Вся сложная логика фиксации сосредоточена в одном месте, таким образом, координируется запись в базу данных. |
Factory Method или Виртуальный конструктор (Virtual Constructor) - GoF
Проблема | Определить интерфейс для создания объекта, но оставить подклассам решение о том, какой класс инстанцировать, то есть, делегировать инстанцирование подклассам. | |
Решение | Абстрактный класс "Создатель" объявляет ФабричныйМетод, возвращающий объект типа "Продукт" (абстрактный класс, определяющий интерфейс обьектов, создаваемых фабричным методом). "Создатель также может определить реализацию по умолчанию ФабричногоМетода, который возвращает "КонкретныйПродукт". "КонкретныйСоздатель" замещает ФабричныйМетод, возвращающий объект "КонкретныйПродукт". "Создатель" "полагается" на свои подклассы в определении ФабричногоМетода, возвращающего объект "КонкретныйПродукт". | |
Преимущества | Избавляет проектировщика от необходимости встраивать в код зависящие от приложения классы. | |
Недостатки | Возникает дополнительный уровень подклассов. |
Файловый обмен
Описание | Данный тип интеграции основывается на концепции "Точка - Точка", 5.1.1, системы экспортируют общие данные в формате пригодном для импорта в другие системы. В последнее время в качестве единого формата файлов обмена все чаще выбирают XML, как наиболее распространенный и поддерживаемый в мире, большинство систем позволяют производить экспорт-импорт данных в формате XML, на рынке программного обеспечения существует большое количество программ, позволяющих в удобной форме создавать так называемые "преобразователи" XML данных на основе технологии XSLT. | |
Недостатки | Необходим сотрудник, который ответственен за регулярность проведения операций экспорта-импорта, корректности этих операций, а также за соблюдение формата обмена и, возможно за процесс преобразования форматов, т.к. несоответствие форматов экспорта и импорта является частой ситуацией. |
Фасад (Facade) - GoF
Проблема | Как обеспечить унифицированный интерфейс с набором разрозненных реализаций или интерфейсов, например, с подсистемой, если нежелательно высокое связывание с этой подсистемой или реализация подсистемы может измениться? |
Решение | Определить одну точку взаимодействия с подсистемой - фасадный объект, обеспечивающий общий интерфейс с подсистемой и возложить на него обязанность по взаимодействию с ее компонентами. Фасад - это внешний объект, обеспечивающий единственную точку входа для служб подсистемы. Реализация других компонентов подсистемы закрыта и не видна внешним компонентам. Фасадный объект обеспечивает реализацию паттерна "Устойчивый к изменениям" с точки зрения защиты от изменений в реализации подсистемы., см. п. . |
Функционально-центрический (function-centric) подход.
Описание | При функционально-центрическом подходе основным системообразующим фактором являются сервисы - общеупотребительные прикладные и системные функции коллективного доступа, реализованные в виде серверных программ со стандартным API. В виде сервисов реализуются такие функции, как различного вида прикладная обработка, контроль информационной безопасности, служба единого времени, централизованный файловый доступ и т.п. Все сервисы являются интегрированными в том же смысле, что и интегрированные данные в базе данных коллективного доступа, т.е. реализуемые сервисами функции достоверны, непротиворечивы и общедоступны. Концепция интеграции в данном подходе состоит в том, что приложения объединяются в систему вокруг интегрированных сервисов со стандартизованным интерфейсом. Интегрирующей средой является сервер приложений или монитор транзакций со стандартным API. При использовании функционально-центрического подхода приложение декомпозируется на три уровня (взаимодействие с пользователем, прикладная обработка, доступ к данным). Общая архитектура системы является трехзвенной: клиентское приложение - функциональные сервисы - сервер базы данных. |
Хранитель (Memento) - GoF
Проблема | Необходимо зафиксировать поведение объекта для реализации, например, механизма отката. | |
Решение | Зафиксировать и вынести (не нарушая инкапсуляции) за пределы объекта его внутреннее состояние так, чтобы впоследствии можно было восстановить в нем объект. "Хранитель" сохраняет внутреннее состояние объекта "Хозяин" и запрещает доступ к себе всем другим объектам кроме "Хозяина", который имеет доступ ко всем данным для восстановления в прежнем состоянии. "Посыльный" может лишь передавать "Хранителя" другим объектам. "Хозяин" создает "Хранителя", содержащего снимок текущего внутреннего состояния и использует "Хранитель" для восстановления внутреннего состояния. "Посыльный" отвечает за сохранение "Хранителя", при этом не производит никаких операций над "Хранителем" и не исследует его внутреннее содержимое. "Посыльный" запрашивает "Хранитель" у "Хозяина", некоторое время держит его у себя, а затем возвращает "Хозяину". | |
Преимущества | Не раскрывается информация, которая доступна только "Хозяину", упрощается структура "Хозяина". | |
Недостатки | С использованием "Хранителей" могут быть связаны значительные издержки, если "Хозяин" должен копировать большой объём информации, или если копирование должно проводиться часто. |
Информационный эксперт (Information Expert)- GRASP
Проблема | В системе должна аккумулироваться, рассчитываться и т. п. необходимая информация. | |
Решение | Назначить обязанность аккумуляции информации, расчета и т. п. некоему классу (информационному эксперту), обладающему необходимой информацией. | |
Рекомендации | Информационным экспертом может быть не один класс, а несколько. | |
Пример | Необходимо рассчитать общую сумму продажи. Имеются классы проектирования "Продажа", "ТоварПродажа" (продажа отдельного вида товара в рамках продажи в целом), "ТоварСпецификация" (описание конкретного вида товара). Необходимо распределить обязанности по предоставлению информации и расчету между этими классами. Объект "Продажа" должен передать сообщение "Рассчитать промежуточную сумму" каждому экземпляру класса "ТоварПродажа" (которые, в свою очередь, передают сообщения "СообщитьЦену" объектам "ТоварСпецификация", с целью получения информации о цене экземпляра товара), и, затем, просуммировать полученные результаты. Промежуточную сумму рассчитывает объект "Товар Продажа". Таким образом, все три объекта являются информационными экспертами. Диаграмма классов проектирования. | |
Преимущества | Поддерживает инкапсуляцию, то есть объекты используют свои собственные данные для выполнения поставленных задач. | |
Недостатки | Если объект, обладающий наиболее полной информацией, например, о продаже (см. пример - класс "Продажа"), будет отвечать и за сохранение этой информации в базе данных, то получится, что логика приложения (моделирование продажи) и логика связи с базой данных "помещаются" в один класс (нарушение принципа разделения обязанностей основных объектов системы, и, кроме того, логика связи с базой данных будет дублироваться во многих других классах. |
Интеграция на основе единой понятийной модели предметной области (concept-centric).
Задача | Требуется интеграция в рамках единой системы разнородных интегрирующих средств. Данная проблема весьма актуальна для любой информационной системы большого масштаба, в которой применяются различные покупные системы со своими серверами приложений и другими видами программного обеспечения промежуточного слоя. |
Решение | Средством решения проблемы интеграции второго уровня является разработка ОЯВ компонентов, основанного на единой понятийной модели, описывающей объекты предметной области, их взаимосвязи и поведение. Как правило, ОЯВ является языком сообщений высокого уровня и имеет достаточно простой синтаксис и естественно-языковую лексику на основе бизнес-объектов. Единая понятийная модель представляет собой базу метаданных, хранящую описания интерфейсных бизнес-объектов каждого из компонентов и отношения (связи) между этими объектами. Между интегрируемыми компонентами и их описаниями в базе метаданных должно поддерживаться постоянное соответствие. Хранящиеся в базе метаданных описания и сам язык взаимодействия строятся как независимые от конкретного интегрирующего программного обеспечения. Преобразование сообщений на ОЯВ в вызовы функций той или иной интегрирующей среды обеспечивается дополнительной интегрирующей оболочкой с единым интерфейсом, который предназначен только для обмена сообщениями на ОЯВ. Единицей информационного обмена в рассматриваемом подходе являются сообщения, поэтому целесообразно строить такое программное обеспечение на основе программных продуктов класса MOM. |
Интеграция систем по данным (data-centric).
Описание | Данный поход был исторически первым в решении проблемы интеграции приложений. Этот подход характерен для традиционных систем "клиент-сервер". При интеграции приложений по данным считается, что основным системообразующим фактором при построении информационной системы является интегрированная база данных коллективного доступа. Концепция интеграции в этом подходе состоит в том, что приложения объединяются в систему вокруг интегрированных данных под управлением СУБД. Интегрирующей средой является промышленная СУБД (как правило, реляционная) со стандартным интерфейсом доступа к данным (обычно это доступ на SQL). Все функции прикладной обработки размещаются в клиентских программах. |
Недостатки | Необходимость передачи больших объемов данных. |
Интерпретатор (Interpreter ) - GoF
Проблема | Имеется часто встречающаяся, подверженная изменениям задача. | |
Решение | Создать интерпретатор, который решает данную задачу. | |
Пример | Задача поиска строк по образцу может быть решена посредством создания интерпретатора, определяющего грамматику языка. "Клиент" строит предложение в виде абстрактного синтаксического дерева, в узлах которого находятся объекты классов "НетерминальноеВыражение" и "ТерминальноеВыражение" (рекурсивное), затем "Клиент" инициализирует контекст и вызывает операцию Разобрать(Контекст). На каждом узле типа "НетерминальноеВыражение" определяется операция Разобрать для каждого подвыражения. Для класса "ТерминальноеВыражение" операция Разобрать определяет базу рекурсии. "АбстрактноеВыражение" определяет абстрактную операцию Разобрать, общую для всех узлов в абстрактном синтаксическом дереве. "Контекст" содержит информацию, глобальную по отношению к интерпретатору. | |
Преимущества | Грамматику становится легко расширять и изменять, реализации классов, описывающих узлы абстрактного синтаксического дерева похожи (легко кодируются). Можно легко изменять способ вычисления выражений. | |
Недостатки | Сопровождение грамматики с большим числом правил затруднительно. |
Искусственный (Pure Fabrication) - GRASP
Проблема | Какой класс должен обеспечивать реализацию паттернов , и ? | |
Решение | Присвоить группу обязанностей с высокой степенью зацепления классу, который не представляет конкретного понятия из предметной области (синтезировать искусственную сущность для обеспечения высокого зацепления и слабого связывания). | |
Пример | См. пример паттерна "Информационный эксперт" . Какой класс должен сохранять экземпляры класса "Продажа" в реляционной базе данных? Если возложить эту обязанность на класс "Продажа", то будем иметь низкую степень зацепления и высокую степень связывания (поскольку класс "Продажа" должен быть связан с интерфейсом реляционной базы данных. Хранение обьектов в реляционной базе данных - это общая задача, которую придется решать для многих классов. Решением данной проблемы будет создание нового класса "ПостоянноеХранилище", ответственного за сохранение обьектов некоторого вида в базе данных. | |
Преимущества | Класс "ПостоянноеХранилище" будет обладать низкой степенью связывания и высокой степенью зацепления. | |
Недостатки | Данным паттерном не следует злоупотреблять иначе все функции системы превратятся в объекты. |
Итератор (Iterator) или Курсор (Cursor) - GoF
Проблема | Составной объект, например, список, должен предоставлять доступ к своим элементам (объектам), не раскрывая их внутреннюю структуру, причем перебирать список требуется по-разному в зависимости от задачи. | |
Решение | Создается класс "Итератор", коорый определяет интерфейс для доступа и перебора элементов, "КонкретныйИтератор" реализует интерфейскласса "Итератор" и следит за текущей позицией при обходе "Агрегата". "Агрегат" определяет интерфейс для создания объекта - итератора. "КонкретныйАгрегат" реализует интерфейс создания итератора и возвращает экземпляр класса "КонкретныйИтератор", "КонкретныйИтератор" отслеживает текущий объект в агрегате и может вычислить следующий объект при переборе. | |
Преимущества | Поддерживает различные способы перебора агрегата, одновременно могут быть активны несколько переборов. |
Клиент/сервер
Описание | Данные и процессы системы распределены между несколькими процессорами. Паттерн имеет три основных компонента: набор автономных серверов, (предоставляют сервисы другим подсистемам), набор подсистем - клиентов (которые вызывают сервисы, предоставляемые серверами) и сеть (служит для доступа клиентов к сервисам). Клиенты должны знать имена серверов и сервисов, в то время как серверам не надо знать имена клиентов и их количество. Клиенты получают доступ к сервисам, предоставляемым серверами посредством удаленного вызова процедур. |
Рекомендации | Данный подход можно использовать при реализации систем, основанных на репозитории, который поддерживается как сервер системы. Подсистемы, имеющие доступ к репозиторию, являются клиентами. |
Преимущества | Данный паттерн формирует распределенную архитектуру, ее эффективно использовать в сетевых системах с множеством распределенных процессоров В систему легко добавить новый сервер и интегрировать его с остальной частью системы или же обновить сервисы, не воздействуя на другие части системы. |
Недостатки | При работе серверы и клиенты обмениваются данными, но при большом объеме передаваемых между серверами и клиентами данных могут возникнуть проблемы с пропускной способностью сети. |
Коллекция обьектов (Identity Map)
Задача | Требуется гарантировать, что каждый объект будет загружен из базы данных только один раз. |
Решение | Создать специальную коллекцию обьектов, загруженных из базы данных в пределах одной бизнес - транзакции. Таким образом, при получении запроса можно просмотреть эту коллекцию в поисках нужного объекта. |
Преимущества | Предотвращение повторных загрузок позволяет избежать ошибок и повышает производительность системы. |
Команда (Command), Действие (Action) или Транзакция (Транзакция) - GoF
Проблема | Необходимо послать объекту запрос, не зная о том, выполнение какой операции запрошено и кто будет получателем. | |
Решение | Инкапсулировать запрос как объект. "Клиент" создает объект "КонкретнаяКоманда", который вызывает операции получателя для выполнения запроса, "Инициатор" отправляет запрос, выполоняя операцию "Команды" Выполнить(). "Команда" объявляет интерфейс для выполнения операции, "КонкретнаяКоманда" определяет связь между объектом "Получатель" и операцией Действие(), и, кроме того, реализует операцию Выполнить() путем вызова соответствующих операций объекта "Получатель". "Клиент" создает экземпляр класса "КонкретнаяКоманда" и устанавливает его получателя, "Инициатор" обращается к команде для выполнения запроса, "Получатель" (любой класс) располагает информацией о способах выполнения операций, необходимых для выполнения запроса. | |
Преимущества | Паттерн "Команда" разрывает связь между объектом, инициирующим операции, и объектом, имеющим информацию о том, как ее выполнить, кроме того создается объект "Команда", который можно расширять и манипулировать им как объектом. |
Компоновщик (Composite) - GoF
Проблема | Как обрабатывать группу или композицию структур обьектов одновременно? |
Решение | Определить классы для композитных и атомарных обьектов таким образом, чтобы они реализовывали один и тот же интерфейс. |
Пример | См. паттерн "Стратегия", 3.2.9, необходимо учесть несколько скидок различных видов (зависят от времени, типа покупателя, типом выбранного продукта. Как применять политику ценообразования? Вырабатывается стратегия приоритета скидок, объект "Продажа" не должен обладать информацией о применяемых скидках, но можно было бы применить стратегию расчета скидок. Создается новый класс "РасчетСкидкиАлгоритмКомпозит". |
Контроллер (Controller) - GRASP
Проблема | "Кто" должен отвечать за обработку входных системных событий? |
Решение | Обязанности по обработке системных сообщений делегируются специальному классу. Контроллер - это объект, который отвечает за обработку системных событий и не относится к интерфейсу пользователя. Контроллер определяет методы для выполнения системных операций. |
Рекомендации | Для различных прецедентов логично использовать разные контроллеры (контроллеры прецедентов) - контроллеры не должны быть перегружены. Внешний контроллер представляет всю систему целиком, его можно использовать, если он будет не слишком перегруженным (то есть, если существует лишь несколько системных событий). |
Преимущества | Удобно накапливать информацию о системных событиях (в случае, если системные операции выполняются в некоторой определенной последовательности). Улучшаются условия для повторного использования компонентов (системные события обрабатываются Контроллером а не элементами интерфейса пользователя). |
Недостатки | Контроллер может оказаться перегружен. |
ЛИТЕРАТУРА
[1] K. Alexander et al. Pattern Language. Oxford 1977.
[2] К. Ларман. Применение UML и паттернов проектирования. М. , Вильямс, 2002.
[3] Г. Буч, Дж. Рамбо, А. Джекобсон. Язык UML. Руководство пользователя. М. LVR Пресс, 2001.
[4] Э. Гамма, Р. Хелм, Р. Джонсон, Дж. Влиссидес. Приемы обьектно - ориентированного проектирования Паттерны Проектирования. СПб., Питер, 2003.
[5] М. Фаулер. Архитектура корпоративных программных приложений. М. , Вильямс, 2004.
[6] G. Hohpe, B. Woolf. Enterprise Integration Patterns : Designing, Building, and Deploying Messaging Solutions. Addison-Wesley, 2004.
Многоуровневая система (Layers) или абстрактная машина
Описание | В соответствии с паттерном "Многоуровневая система" структурные элементы системы организуются в отдельные уровни со взаимосвязанными обязанностями таким образом, чтобы на нижнем уровне располагались низкоуровневые службы и службы общего назначения, а на более высоких - объекты уровня логики приложения. При этом взаимодействие и связывание уровней происходит сверху вниз. Связывания обьектов снизу вверх следует избегать.
На рисунке показаны типичные уровни логической архитектуры системы . Слой представления охватывает все, что имеет отношение к общению пользователя с системой. К главным функциям слоя представления относится отображение информации и интерпретация вводимых пользователем команд с преобразованием их в соответствующие операции в контексте домена (бизнес - логики) и источника данных. Источник данных - подмножество функций, обеспечивающих взаимодействие со сторонними системами, которые выполняют В отличие от архитектурного паттерна "Клиент - сервер" 4.1.2, слои вовсе не обязательно должны располагаться на разных машинах. |
Пример | Примером данного подхода может служить модель взаимодействия открытых систем (OSI - Open System Interconnection - международная программа стандартизации обмена данными между компьютерными системами на основе семиуровневой модели протоколов передачи данных в открытых системах). |
Преимущества | Многоуровневая система может быть разработана пошагово (итеративно). |
Недостатки | Изменение исходного кода влечет за собой переделку всех элементов системы, поскольку все элементы системы тесно связаны друг с другом.
Логика приложения тесно связана с интерфейсом пользователя - затруднительно менять интерфейс или принципы реализации логики. Из-за высокой связанности, работу по реализации системы сложно разделить между разработчиками и, кроме того, сложно модифицировать функции приложения или переходить на новые технологии. |
Мост (Bridge), Handle (описатель) или Тело (Body) - GoF
Проблема | Требуется отделить абстракцию от реализации так, чтобы и то и другое можно было изменять независимо. При использовании наследования реализация жестко привязывается к абстракции, что затрудняет независимую модификацию. | |
Решение | Поместить абстракцию и реализацию в отдельные иерархии классов. | |
Рекомендации | Можно использовать если, например, реализацию необходимо выполнять во время реализации программы. | |
Пример | "Абстракция" определяет интерфейс "Абстракции" и хранит ссылку на объект "Реализация", "УточненнаяАбстракция" расширяет интерфейс, определенный "Абстракцией". "Реализация" определяет интерфейс для классов реализации, он не обязан точно соответствовать интерфейсу класса "Абстракция" - оба интерфейса могут быть совершенно различны. Обычно интерфецйс класса "Реализация" предоставляет только примитивные операции, а класс "Абстракция" определяет операции более высокого уровня, базирующиеся на этих примитивных. "КонкретнаяРеализация" содержит конкретную реализацию класса "Реализация". Объект "Абстракция" перенаправляет своему объекту "Реализация" запросы "Клиента". | |
Преимущества | Отделение реализации от интерфейса, то есть, "Реализацию" "Абстракции" можно конфигурировать во время выполнения. Кроме того, следует упомянуть, что разделение классов "Абстракция" и "Реализация" устраняет зависимости от реализации, устанавливаемые на этапе компиляции: чтобы изменить класс "Реализация" вовсе не обязательно перекомпилировать класс "Абстракция". |
Наблюдатель (Observer), Опубликовать
Проблема | Один объект ("Подписчик") должен знать об изменении состояний или некоторых событиях другого объекта. При этом необходимо поддерживать низкий уровень связывания с объектом - "Подписчиком". |
Решение | Определить интерфейс "Подписки". Объекты - подписчики реализуют этот интерфейс и динамически регистрируются для получении информации о некотором событии. Затем при реализации условленного события оповещаются все объекты - подписчики. |
Наследование с одной таблицей (Single Table Inheritance)
Задача | Поскольку SQL не предоставляет стандартных инструментов поддержки наследования, требуется создать специальный аппарат отображения в базе данных иерархии наследования. | |
Решение | Все поля всех классов наследования отображаются в одной и той же таблице. Например, требуется отобразить структуру
При использовании паттерна "Наследование с одной таблицей" формируется следующая таблица | |
Преимущества | Данный метод прост в реализации и устойчив к модификациям. | |
Недостатки | При работе пользователей с одной большой таблицей будет вводиться много блокировок. |
Не разговаривайте с неизвестными (Don't talk to strangers) - GRASP
Проблема | Обеспечить связь клиентского объекта с непрямыми объектами (то есть известными другим объектам, а не самому клиенту). |
Решение | Необходимо избегать проектных решений, предполагающих передачу сообщений с удаленными непрямыми объектами (незнакомцами). Решением может быть частный случай паттерна "Устойчивый к изменениям", см. . Прямым объектом потребуются новые операции. |
Преимущества | Обеспечивает устойчивость системы к изменению структуры обьектов. |
Низкая связанность (Low Coupling) - GRASP
Проблема | Обеспечить низкую связанность при создании экземпляра класса и связывании его с другим классом. | |
Решение | Распределить обязанности между объектами так, чтобы степень связанности оставалась низкой. | |
Пример | Необходимо создать экземпляр класса "Платеж". В предметной области регистрация объекта "Платеж" выполняется объектом "Регистрация" (ведется рестр). Ниже приводятся 2 способа создания экземпляра класса "Платеж". Верхний рисунок - с использованием паттерна "Создатель", нижний - с использованием "Низкая связанность". Последний способ обеспечивает более низкую степень связывания. |
Объектно-центрический (object-centric).
Описание | Объектно-центрический подход, основанный на стандартах объектного взаимодействия CORBA, COM/DCOM, .NET и пр. и является композицией типов объединения систем по данным и обьектно - центрического. Концепция интеграции в состоит в том, что системы объединяются вокруг общедоступных распределенных объектов со стандартными интерфейсами. Характерными особенностями данного подхода являются: " унифицированный язык спецификации интерфейсов объектов (например IDL); " отделение реализации компонентов от спецификации их интерфейсов; " общий механизм поддержки взаимодействия объектов (брокер объектных запросов, играющий роль "общей шины", поддерживающей взаимодействие объектов). Интегрирующей средой является брокер объектных запросов с интерфейсом в стандарте CORBA или DCOM. Общая архитектура системы формируется на основе распределенных объектов и является n-звенной. |
Обьектно - ориентированный, Модель предметной области (Domain Model), модуль таблицы (Data Mapper)
Задача | Бизнес - логика крайне сложна, имеется множество правил и условий, оговаривающих различные варианты поведения системы. | |
Решение | Система представляется состоящей из совокупности связанных между собой обьектов. Объекты представляют сервисы (методы) другим объектам и создаются во время исполнения программы на основе определения классов обьектов. Объекты скрывают информацию о представлении состояний и, следовательно, ограничивают к ним доступ. | |
Преимущества | Упрощается процесс модификации системы: можно изменять реализацию того или иного объекта, не воздействуя на другие объекты. Обьектно - ориентированная система проще в понимании и модернизации. Данная система удобна для групповой разработки: работу по реализации системы легко разделить между разработчиками. Потенциально все объекты являются повторно используемыми компонентами, так как они независимо инкапсулируют данные о состоянии и операции. Архитектуру системы можно разрабатывать на базе обьектов (структур обьектов) уже созданных в предыдущих проектах. | |
Недостатки | При использовании сервисов объекты должны явно ссылаться на имена других обьектов и знать их интерфейс (это необходимо учесть если при изменении системы требуется изменить интерфейс). | |
Пример 1. | Модель предметной области может быть рассмотрена как частный случай данного паттерна. Каждый объект наделяется только функциями, отвечающими его природе. На диаграмме показано вычисление зачтенного дохода с помощью модели предметной области, см. пример из п. . | |
Пример 2. | Модуль таблицы также является частным случаем данного паттерна. В отличие от модели предметной области Модуль таблицы содержит по одному объекту Контракт для каждого контракта, а Модуль таблицы является единственным объектом. Модуль таблицы используется совместно с множеством записей (Record Set). Сначала создается объект "Контракт", затем - "Продукт", множество записей передается ему в качестве аргумента.. Для совершения операций над отдельным контрактом, следует сообщить объекту соответствующий идентификатор (Id).
Модуль таблицы представляет собой промежуточный вариант между "Сценарием транзакции" 4.2.1.1 и "Моделью предметной области" (Пример1). |
Обмен сообщениями
Описание | Данный тип интеграции приложений основан на асинхронном обмене сообщениям посредством шины данных и предназначен для интеграции независимых приложений без или с минимальными доработками существующих систем. Он является реализацией подхода 5.2.4. При этом за логику интеграции отвечает интеграционная шина в отличие от других типов интеграции, где за логику интеграции отвечала одна из интегрируемых систем. Такой подход позволяет легко интегрировать новые системы, а также изменять логику интеграции, легко приводя ее в соответствие с бизнес логикой процесса. |
Общая база данных
Описание | Является реализацией подхода 5.2.1. Данный тип интеграции позволяет получить полностью интегрированную систему приложений, работающую с едиными данными в любой момент времени. Изменения, произведенные в одном из приложений, автоматически отражаются в другом. За корректность данных отвечает многопользовательская СУБД.
Затруднительно интегрировать существующие системы, удобно использовать для вновь создаваемых. |
систем.
Общие термины
Rational Rose - инструмент для визуального моделирования объектно-ориентированных информационных систем компании Rational Software. Продукт использует UML.
API (Application Programming Interface) - интерфейс программирования прикладных систем.
UML (Unified Modeling Language) - унифицированный язык моделирования обьектно - ориентированных программных систем.
Анализ - исследование обьектов и процессов предметной области, кроме того, данный термин может означать исследование требований к системе, имеющегося функционала системы и пр.
Архитектура системы - организация и структура основных элементов системы, имеющая принципиальное значение для функционирования системы в целом.
Диаграмма - графическое представление набора элементов разрабатываемой системы или предметной области, в вершинах данного представления находятся сущности, а дуги представляют собой отношения этих сущностей. Диаграммы строятся в рамках определенной модели. Например, в рамках UML строятся следующие диаграммы: - прецедентов (описывает функциональное назначение системы), - концептуальных классов (описывает предметную область), - состояний (описывает поведения зависимых от состояний обьектов системы), - деятельности (используется для алгоритмического описания поведения системы) - программных классов, - взаимодействия (описывает взаимодействие обьектов системы).
Проектирование - выработка концептуальных решений, обеспечивающих выполнение основных требований и разработка системной спецификации.
Модель - представление разрабатываемой системы или предметной области в рамках определенного стандарта, например, модель данных системы, выполненная c использованием стандарта IDEF1X.
Модуль - компонент системы (подсистемы), который предоставляет один или несколько сервисов. Модуль может использовать сервисы, поддерживаемые другими модулями. Модуль не может рассматриваться как независимая система.
Подсистема - часть системы, которая выделяется при проектировании архитектуры. Операции выполняемые подсистемой не зависят от сервисов, предоставляемых другими подсистемами, и, кроме того, подсистемы имеют интерфейсы, посредством которых взаимодействуют с другими подсистемами.
Общие термины - часть
Подсистемы могут состоять из модулей или представлять собой группу классов.
Предметная область - область знаний или деятельности, характеризующаяся специальной терминологией, используемой экспертами предметной области, и набором бизнес - правил.
Проектирование - выработка концептуальных решений, обеспечивающих выполнение основных требований и разработка системной спецификации.
Принцип разделения обязанностей - разделение различных аспектов функционирования системы, то есть, разделение системы на элементы, соответствующие разным аспектам функционирования и задачам. Например, программные объекты уровня предметной области должны отвечать только за реализацию логики приложения, а взаимодействие с внешними службами должны обеспечивать отдельные группы обьектов.
Система - совокупность взаимодействующих компонентов, работающих совместно для достижения определенных целей.
Событие - происшествие в системе, значимое для обеспечения требуемого функционала. Событие может быть внешним по отношению к системе и внутренним, то есть инициируемым самой системой.
Требования к системе - условия или возможности, которые система должна выполнять или предоставлять, и, кроме того, соглашение между заказчиком системы и ее разработчиком об этих условиях или возможностях.
Паттерн проектирования представляет собой именованное описание проблемы и ее решения, кроме того, содержит рекомендации по применению в различных ситуациях, описание достоинств и недостатков.
паттерн проектирования объектов - GoF - паттерны, разработанные четырьмя авторами , GRASP (General Responsibility Assignment Software Patterns) - паттерны распределения обязанностей между объектами ; архитектурный системный паттерн - крупномасштабное проектное решение при разработке системы, обычно формируется на ранних итерациях ; паттерн интеграции систем - используется при интеграции нескольких систем . |
Одиночка (Singleton) - GoF
Проблема | Какой специальный класс должен создавать "Абстрактную фабрику", см. и как получить к ней доступ? Необходим лишь один экземпляр специального класса, различные объекты должны обращаться к этому экземпляру через единственную точку доступа. |
Решение | Создать класс и определить статический метод класса, возвращающий этот единственный объект. |
Рекомендации | Разумнее создавать именно статический экземпляр специального класса, а не объявить требуемые методы статическими, поскольку при использовании методов экземпляра можно применить механизм наследования и создавать подклассы. Статические методы в языках программирования не полиморфны и не допускают перекрытия в производных классах. Решение на основе создания экземпляра является более гибким, поскольку впоследствии может потребоваться уже не единственный экземпляр объекта, а несколько. |