Содержание курса
Инфраструктура (ландшафт) для организации проектной деятельности
Инжиниринг бизнес-процессов заказчика. 1. Применение UML Activity
Разработка логической структуры данных. 2. Паттерны проектирования применительно к структуре данных.
Моделирование поведения целевой системы. Моделирование процессов управления
Формирование спецификаций требований на создание целевой ИС
Управление изменениями требований и организация эффективного взаимодействия в команде производства ИТ продукта
Организация процессов проектирования в производстве ИТ-продукта
6. Паттерны проектирования применительно к сущностям
В 1950 году математик по имени Клод Шеннон опубликовал в журнале статью «Как запрограммировать компьютер для игры в шахматы». В этой статье он подсчитал, что количество комбинаций в шахматах будет равно 10120. Это на самом деле превосходит количество атомов в известной Вселенной, которое оценивается от 1078 до 1082 атомов.

Но среднестатистическому шахматисту для успешного старта не обязательно изучать все существующие варианты начала игры, а достаточно выбрать несколько популярных дебютов за каждый цвет.
По факту этот пример иллюстрирует использование формализованных шаблонов успешных тактических розыгрышей для предсказуемого достижения желаемых результатов.
Подобным образом успешные шаблоны используют и в ИТ. Для того, чтобы при решении однотипных задач проектирования не изобретать каждый раз велосипед, принято использовать паттерны проектирования. Давайте рассмотрим некоторые из них, применительно к моделированию хранилищ данных.
Приспособленец (Flyweight) - структурный паттерн проектирования, который нужен для эффективной работы с большим количеством мелких объектов.
Основная идея: разделить общее состояние объектов и вынести его в отдельное место, чтобы не плодить кучу таблиц и связей, экономить место. При этом объект, представляет себя как уникальный экземпляр в разных местах программы, но фактически не являющийся таковым.
Предполагает обычно использование двух таблиц:
Тип объекта — общая часть для многих объектов (например: Приоритет, Пол, Вид заявки).
Перечень значений — уникальное для каждого объекта (например: Срочный, Средний), с указанием к какому типу относится.

Если нам необходимо использовать множество небольших Справочников, например, «Приоритет», «Тип Бронирования», «Вид заявки», «Тип читателя», "Пол" и прочие, то добавление класса для каждого такого справочника приведет к созданию большого количества объектов, которые придется поддерживать. Какие же есть альтернативы?
Можно создать класс, "Тип параметра" и связанный класс "Значение параметра" смотри на рисунок выше. В качестве типов используем название перечисленных нами мини-справочников. А в качестве значений, содержание строк этих справочников, с ссылкой относящей к типу. Для такого варианта желательно также реализовать интерфейс, который по типу справочника, позволит работать с ним как с отдельным объектом системы.
Компоновщик (Composite) - это структурный паттерн проектирования, который нужен, чтобы работать одинаково с отдельными объектами и группами объектов.
Ключевая идея: дерево объектов, где отдельный элемент и группа элементов — одно и то же с точки зрения клиента.
Удобно применять если необходимо:
Организовать иерархию объектов (например, папки и файлы).
Иметь возможность работать единообразно как с одним файлом, так и с целой папкой.
Проводить операции рекурсивно: считать размер папки, удалить всё внутри, найти что-то и т.д.

В качестве примера, можно рассмотреть универсальный Классификатор, который представляет из себя класс группы и класс «значений», входящих в группу (соответствует паттерну Приспособленец). Для присваивания значения классификатора некому объекту, используется класс «Классификация объекта», который сопоставляет в себе ссылки на: 1)Группу классификатора, 2)Значение классификатора и на 3)Объект системы, к которому применяется классификация с указанием содержания(значения). Да, структура денормализованая, но в этом решении есть свои нюансы. При этом таблица Классификатор содержит рекурсивную ссылку на себя и позволяет строить древовидную структуру. Так же для управления правилами выбора можно использовать дополнительные характеристики. Например, "Один из", указывающую на возможность выбрать только одно или множество значений из группы и характеристика "Можно выбрать", указывающая на возможность /невозможность выбрать элемент на текущем уровне иерархии.
Как можно привести рассмотренную модель к Нормальным формам (NF)? Какие преимущества в данном контексте дает денормализованная форма?
Заместитель (Proxy) - это структурный паттерн, который ставит объект-посредник между клиентом и реальным объектом.
Ключевая идея: клиент работает как будто с реальным объектом, но на самом деле общается с "заменителем", который, например, контролирует доступ, добавляет поведение, откладывает загрузку, логирует, проверяет права и так далее.

Например, на рисунке выше, Пользователь не имеет доступ к значениям Классификатора напрямую. Он может обратиться к интерфейсу, который в соответствии с правами доступа, указанными в таблице «Редактор классификатора», предоставит информацию только о доступных пользователю Классификациях.
Примеры применения паттерна Заместитель:
Virtual Proxy - Лениво загружает файлы или каталоги только при обращении
Protection Proxy - Проверяет права пользователя перед доступом к данным
Remote Proxy - Делает вид, что работает с локальным хранилищем, но на самом деле — через сеть (например, через API)
Caching Proxy - Кэширует файлы, метаданные или результаты запросов
Logging Proxy - Логирует все обращения к данным
Фасад (Facade) - структурный паттерн проектирования, который предоставляет упрощённый интерфейс к сложной подсистеме.
То есть, вместо того чтобы клиент "разрывался" между разными сервисами, классами, модулями, он работает через одно общее «окно доступа».
Например, класс Формуляр книги, может собрать всю информацию о книге, компонуя ее из разных классов. Включая: место хранения, каталогизатор, историю выдачи издания и прочее.

Состояние - Используется в тех случаях, когда во время выполнения программы объект должен менять своё поведение в зависимости от своего состояния.
Например, в зависимости от текущего статуса книги, для нее доступна одна из операций «Выдача» или «Возврат».

Преимущества паттерна Состояние для хранилищ:
Поведение хранилища чётко связано с текущим состоянием, без нагромождения условных переходов.
Легко добавлять новые состояния без переписывания всей логики.
Повышается читаемость и расширяемость кода.
Удобно покрывать тестами каждое состояние отдельно.
Паттерн Состояние очень удобно использовать совместно с диаграммами BPMN, для "умного" выбора действия над объектом, из доступного ассортимента в текущем состоянии . В следующей части мы будем разбирать поведенческие модели и в том числе диаграмму Состояний.
Коллаборация паттернов Фасад (Facade) / Состояние (State)
1) Фасад (StorageFacade) — это единая точка входа для клиента. Клиенту не нужно знать о состоянии, он просто вызывает метод.
2) Состояние (StorageState) — определяет, как именно работают методы в зависимости от текущего состояния хранилища:
инициализация,
рабочее состояние,
ошибка,
миграция и т.д.
3) Фасад внутри себя держит ссылку на состояние и перекидывает вызовы методам состояния.
Прототип (Prototype) - порождающий паттерн, который, позволяет создавать новые объекты копированием уже существующего экземпляра-прототипа, вместо создания объекта с нуля через конструктор.
Иными словами, можно копировать существующий объект в новый, вместо его создания с "0". Это быстро, удобно, без необходимости всё настраивать заново.
При этом используется инструмент - "Реестр прототипов", представляющий хранилище (словарь), где мы:
1) регистрируем прототипы (например, LocalStorage, S3Storage, InMemoryStorage);
2) по запросу клонируем нужный прототип;
3) при необходимости — донастраиваем клоны.
7. Адаптивные модели данных
Еще одна возможность снизить сложность, вызванную использованием большого количества сущностей, это применение механизмов универсализации обработки данных. Например: использование шаблонов - Типовых бизнес-объектов, на основе которых создаются экземпляры. Такие модели называются адаптивными.
Понятие управления с адаптацией подразумевает управление в системе с неполной априорной информацией об управляемом процессе, которое изменяется по мере накопления информации и применяется с целью улучшения качества работы системы. Для практикования подобных подходов можно использовать например:
Шаблонный метод (Template method) - паттерн проектирования (поведенческий), который: определяет скелет алгоритма в методе базового класса, а отдельные шаги этого алгоритма делегирует на переопределение в подклассы.
Иными словами: базовый класс описывает общий план действий. Подклассы могут кастомизировать детали, не меняя структуру процесса. Определяет основу алгоритма и позволяет наследникам переопределять некоторые шаги алгоритма, не изменяя его структуру в целом. На диаграмме ниже представлен пример организации шаблона "Карты заданий", позволяющий быстро и точно создавать цепочки задач для исполнителей.

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