94
обязанностей (chain of responsibility), команда (command), фасад (facade), посредник
(mediator), наблюдатель (observer). Для повышения независимости отдельных классов
подсистемы друг от друга используются паттерны: адаптер (adapter), декоратор (decorator),
посетитель (visitor).
• использование имени класса при создании объекта привязывает проектировщика к
конкретной реализации, а не к интерфейсу, что может осложнить изменение объектов в
будущем. Решение этой проблемы состоит
в косвенном создании объектов с помощью
паттернов абстрактная фабрика, фабричный метод (factory method), прототип
(prototype);
• использование конкретной операции ограничивает выполнение запроса одним единственным
способом. Паттерны цепочка обязанностей и команда позволяют, не включая запросы в код,
изменить способ удовлетворения запроса, как на этапе компиляции, так и на этапе
выполнения;
• ограничить зависимость
от конкретной платформы (операционной системы с
предоставляемой ее API) позволяют паттерны абстрактная фабрика и мост;
• если при построении клиента использовалась информация о том, как тот или иной объект
представлен, храниться или реализован, то при изменении объекта может потребоваться
изменить клиент. Инкапсуляцию перечисленной информации обеспечивают паттерны
абстрактная фабрика, мост, хранитель (memento), заместитель (proxy)
;
• объекты, зависящие от изменяющихся алгоритмов (в случае необходимости расширения,
оптимизации и т.д.), приходится перепроектировать. Паттерны мост, итератор (iterator),
стратегия (strategy), шаблонный метод (template method) и посетитель позволяют
изолировать алгоритмы с высокой вероятностью изменения;
• композиция объектов и делегирование – гибкие альтернативы наследования для
комбинирования поведения, поскольку в этом случае новая функциональность
добавляется в
систему посредством изменения способа композиции объектов, а не за счет определения
новых подклассов через наследование. Однако использование только композиции объектов
может существенно усложнить структуру проекта. В этой связи используют прием, при
котором вначале определяется подкласс, а затем для обеспечения требуемой специализации
выполняется комбинирование его объектов с существующими. Такой прием
нашел отражение
в следующих паттернах: мост, цепочка обязанностей, компоновщик (composite),
декоратор (decorator), наблюдатель, стратегия.
Определив обязанности классов, введя системные класса, а также, рассмотрев интерфейсы
классов в соответствии с паттернами GRASP и GoF, переходят к описанию более высокоуровневых
абстракций – архитектурных слоев ИС.
Первая группа паттернов с которыми мы познакомимся предназначена для
распределения операций, а в более общем понимании обязанностей между классами.
Обязанности и операции относятся друг к другу как целое к частному. Обязанности
включают в себя один или несколько методов, реализация которых в объекте или в
совокупности взаимосвязанных объектов позволяет достичь определенную цель.
В первом приближении можно выделить два типа обязанностей: действие (doing)
(инициирование некоторых операций, их выполнение и управление этим выполнением),
знание (knowing) (хранение информации о инкапсулированных данных, о связанных
объектах, о значениях вычисляемых величин и т.д.).
Паттерны, относящиеся к группе, предназначенной для распределения обязанностей
между классами, получили название GRASP-паттернов (General Responsibility Assignment
Software Patterns). Из числа
GRASP-паттернов наибольшее распространение получили [80]:
(i) информационный эксперт (Information Expert) – правило, позволяющее выбрать
класс (из нескольких кандидатур) для назначения тех или иных функциональных
обязанностей;
(ii) создатель (Creator) – правило, позволяющее назначить классу В обязанность
создавать экземпляры класса А при выполнении определенных условий;
(iii) контроллер (Controller) – создание специального (служебного) класса–
обработчика системных сообщений.