Вопрос 2

В качестве основы проектирования информационных систем применяются "типовые решения" или "шаблоны проектирования" (Patterns).

Шаблоны проектирования (паттерн,design pattern) – это многократно применяемая архитектурная конструкция, предоставляющая решение общей проблемы проектирования в рамках конкретного контекста и описывающая значимость этого решения.

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

В 1970-е годы архитектор Кристофер Александр составил набор шаблонов проектирования. В области архитектуры эта идея не получила такого развития, как позже в области программной разработки. Согласно определению Кристофера Александера: "Каждое типовое решение описывает некую повторяющуюся проблему и ключ к ее разгадке, причем таким образом, что вы можете пользоваться этим ключом многократно, ни разу не придя к одному и тому же результату".

В 1987 году Кент Бэк и Вард Каннигем взяли идеи Александра и разработали шаблоны применительно к разработке программного обеспечения для разработки графических оболочек на языке Smalltalk.

В 1988 году Эрих Гамма начал писать докторскую диссертацию при Цюрихском университете об общей переносимости этой методики на разработку программ.

В 1989-1991 годах Джеймс Коплин трудился над разработкой идиом для программирования на C++ и опубликовал в 1991 году книгу Advanced C++ Idioms. В этом же году Эрих Гамма заканчивает свою докторскую диссертацию и переезжает в США, где в сотрудничестве с Ричардом Хелмом, Ральфом Джонсоном и Джоном Влиссидсом публикует книгу Design Patterns – Elements of Reusable Object-Oriented Software. В этой книге описаны 23 шаблона проектирования. Также команда авторов этой книги известна общественности под названием Банда четырех (Gang of Four, часто сокращается до GoF). Именно эта книга стала причиной роста популярности шаблонов проектирования.

Главная польза каждого отдельного шаблона состоит в том, что он описывает решение целого класса абстрактных проблем. Также тот факт, что каждый шаблон имеет свое имя, облегчает дискуссию об абстрактных структурах данных (ADT) между разработчиками, так как они могут ссылаться на известные шаблоны. Таким образом, за счет шаблонов производится унификация терминологии, названий модулей и элементов проекта.

Правильно сформулированный шаблон проектирования позволяет, отыскав удачное решение, пользоваться им снова и снова.

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

Шаблоны проектирования классифицируют следующим образом:

Паттерны проектирования классов/объектов

  • Структурные паттерны проектирования классов/объектов
  • Адаптер (Adapter) – GoF
  • Декоратор (Decorator) или Оболочка (Wrapper) – GoF
  • Заместитель (Proxy) или Суррогат (Surrogate) – GoF
  • Информационный эксперт (Information Expert)- GRASP
  • Компоновщик (Composite) – GoF
  • Мост (Bridge), Handle (описатель) или Тело (Body) – GoF
  • Низкая связанность (Low Coupling) – GRASP
  • Приспособленец (Flyweight) – GoF
  • Устойчивый к изменениям (Protected Variations) – GRASP
  • Фасад (Facade) – GoF

Паттерны проектирования поведения классов/объектов

  • Интерпретатор (Interpreter ) – GoF
  • Итератор (Iterator) или Курсор (Cursor) – GoF
  • Команда (Command), Действие (Action) или Транзакция (Транзакция) – GoF
  • Наблюдатель (Observer), Опубликовать – подписаться (Publish – Subscribe) или Delegation Event Model – GoF
  • Не разговаривайте с неизвестными (Don't talk to strangers) – GRASP
  • Посетитель (Visitor) – GoF
  • Посредник (Mediator) – GoF
  • Состояние (State) – GoF
  • Стратегия (Strategy) – GoF
  • Хранитель (Memento) – GoF
  • Цепочка обязанностей (Chain of Responsibility) – GoF
  • Шаблонный метод (Template Method) – GoF
  • Высокое зацепление (High Cohesion) – GRASP
  • Контроллер (Controller) – GRASP
  • Полиморфизм (Polymorphism) – GRASP
  • Искусственный (Pure Fabrication) – GRASP
  • Перенаправление (Indirection) – GRASP

Порождающие паттерны проектирования

  • Абстрактная фабрика (Abstract Factory, Factory), др. название Инструментарий (Kit) – GoF
  • Одиночка (Singleton) – GoF
  • Прототип (Prototype) – GoF
  • Создатель экземпляров класса (Creator) – GRASP
  • Строитель (Builder) – GoF
  • Фабричный метод (Factory Method) или Виртуальный конструктор (Virtual Constructor) – GoF

Архитектурные системные паттерны

Структурные паттерны

  • Репозиторий
  • Клиент/сервер
  • Обьектно – ориентированный, Модель предметной области (Domain Model), модуль таблицы (Data Mapper)
  • Многоуровневая система (Layers) или абстрактная машина
  • Потоки данных (конвейер или фильтр)

Паттерны управления

Паттерны централизованного управления

  • Вызов – возврат (сценарий транзакции – частный случай)
  • Диспетчер

Паттерны управления, основанные на событиях

  • Передача сообщений
  • Управляемый прерываниями

Паттерны, обеспечивающие взаимодействие с базой данных

  • Активная запись (Active Record)
  • Единица работы (Unit Of Work)
  • Загрузка по требованию (Lazy Load)
  • Коллекция объектов (Identity Map)
  • Множество записей (Record Set)
  • Наследование с одной таблицей (Single Table Inheritance)
  • Наследование с таблицами для каждого класса (Class Table Inheritance)
  • Оптимистическая автономная блокировка (Optimistic Offline Lock)
  • Отображение с помощью внешних ключей
  • Отображение с помощью таблицы ассоциаций (Association Table Mapping)
  • Пессимистическая автономная блокировка (Pessimistic Offline Lock)
  • Поле идентификации (Identity Field)
  • Преобразователь данных (Data Mapper)
  • Cохранение сеанса на стороне клиента (Client Session State)
  • Cохранение сеанса на стороне сервера (Server Session State)
  • Шлюз записи данных (Row Data Gateway)
  • Шлюз таблицы данных (Table Data Gateway)

Паттерны, предназначенные для представления данных в Web

  • Модель-представление-контроллер (Model View Controller)
  • Контроллер страниц (Page Controller)
  • Контроллер запросов (Front Controller)
  • Представление по шаблону (Template View)
  • Представление с преобразованием (Transform View)
  • Двухэтапное представление (Two Step View)
  • Контроллер приложения (Application Controller)

Паттерны интеграции корпоративных информационных систем

Структурные паттерныны интеграции

  • Взаимодействие "точка – точка"
  • Взаимодействие "звезда" (интегрирующая среда)
  • Смешанный способ взаимодействия

Паттерны по методу интеграции

  • Интеграция систем по данным (data-centric)
  • Функционально-центрический (function-centric) подход
  • Объектно-центрический (object-centric)
  • Интеграция на основе единой понятийной модели предметной области (concept-centric)

Паттерны интеграции по типу обмена данными

  • Файловый обмен
  • Общая база данных
  • Удаленный вызов процедур
  • Обмен сообщениями
  • Также на сегодняшний день существует ряд других шаблонов:
  • Carrier Rider Mapper, предоставление доступа к хранимой информации;
  • аналитические шаблоны, описывают основной подход для составления требований для программного обеспечения (requirement analysis) до начала самого процесса программной разработки;
  • коммуникационные шаблоны, описывают процесс общения между отдельными участниками/сотрудниками организации;
  • организационные шаблоны, описывают организационную иерархию предприятия/фирмы;

Анти-паттерны (Anti-Design-Patterns) описывают как не следует поступать при разработке программ, показывая характерные ошибки в дизайне и в реализации;

и др.

Рассмотрим подробнее некоторые из паттернов проектирования.

Таблица 1. Примеры структурных паттернов классов/объектов
Компоновщик (Composite) – GoF
Проблема Как обрабатывать группу или композицию структур объектов одновременно?
Решение Определить классы для композитных и атомарных объектов таким образом, чтобы они реализовывали один и тот же интерфейс.
Фасад (Facade) – GoF
Проблема Как обеспечить унифицированный интерфейс с набором разрозненных реализаций или интерфейсов, например, с подсистемой, если нежелательно высокое связывание с этой подсистемой или реализация подсистемы может измениться?
Решение Определить одну точку взаимодействия с подсистемой – фасадный объект, обеспечивающий общий интерфейс с подсистемой и возложить на него обязанность по взаимодействию с ее компонентами. Фасад – это внешний объект, обеспечивающий единственную точку входа для служб подсистемы. Реализация других компонентов подсистемы закрыта и не видна внешним компонентам. Фасадный объект обеспечивает реализацию паттерна "Устойчивый к изменениям" с точки зрения защиты от изменений в реализации подсистемы.

 

Таблица 2. Примеры поведенческих паттернов классов/объектов
Итератор (Iterator) или Курсор (Cursor) – GoF
Проблема Составной объект, например, список, должен предоставлять доступ к своим элементам (объектам), не раскрывая их внутреннюю структуру, причем перебирать список требуется по-разному в зависимости от задачи.
Решение Создается класс "Итератор", который определяет интерфейс для доступа и перебора элементов, "КонкретныйИтератор" реализует интерфейс класса "Итератор" и следит за текущей позицией при обходе "Агрегата". "Агрегат" определяет интерфейс для создания объекта – итератора. "КонкретныйАгрегат" реализует интерфейс создания итератора и возвращает экземпляр класса "КонкретныйИтератор", "КонкретныйИтератор" отслеживает текущий объект в агрегате и может вычислить следующий объект при переборе. Данный паттерн поддерживает различные способы перебора агрегата, одновременно могут быть активны несколько переборов.
Посетитель (Visitor) – GoF
Проблема Над каждым объектом некоторой структуры выполняется операция. Определить новую операцию, не изменяя классы объектов.
Решение Клиент, использующий данный паттерн, должен создать объект класса "КонкретныйПосетитель", а затем посетить каждый элемент структуры. "Посетитель" объявляет операцию "Посетить" для каждого класса "КонкретныйЭлемент" (имя и сигнатура данной операции идентифицируют класс, элемент которого посещает "Посетитель" – то есть, посетитель может обращаться к элементу напрямую). "КонкретныйПосетитель" реализует все операции, объявленные в классе "Посетитель". Каждая операция реализует фрагмент алгоритма, определенного для класса соответствующего объекта в структуре. Класс "КонкретныйПосетитель" предоставляет контекст для этого алгоритма и сохраняет его локальное состояние. "Элемент" определяет операцию "Принять", которая принимает "Посетителя" в качестве аргумента, "КонкретныйЭлемент" реализует операцию "Принять", которая принимает "Посетителя" в качестве аргумента. "СтруктураОбьекта" может перечислить свои аргументы и предоставить посетителю высокоуровневый интерфейс для посещения своих элементов. Данный паттерн логично использовать, если в структуре присутствуют объекты многих классов с различными интерфейсами, и необходимо выполнить над ними операции, зависящие от конкретных классов, или если классы, устанавливающие структуру объектов, изменяются редко, но новые операции над этой структурой добавляются часто. Данный паттерн упрощается добавление новых операций, объединяет родственные операции в классе "Посетитель". В данном паттерне затруднено добавление новых классов "КонкретныйЭлемент", поскольку требуется объявление новой абстрактной операции в классе "Посетитель".
Состояние (State) – GoF
Проблема Варьировать поведение объекта в зависимости от его внутреннего состояния
Решение Класс "Контекст" делегирует зависящие от состояния запросы текущему объекту "КонкретноеСостояние" (хранит экземпляр подкласса "КонкретноеСостояние", которым определяется текущее состояние), и определяет интерфейс, представляющий интерес для клиентов. "КонкретноеСостояние" реализует поведение, ассоциированное с неким состоянием объекта "Контекст". "Состояние" определяет интерфейс для инкапсуляции поведения, ассоциированного с конкретным экземпляром "Контекста". Данный паттерн локализует зависящее от состояния поведение и делит его на части, соответствующие состояниям, переходы между состояниями становятся явными.