В.З. Диаграмма взаимодействий

Описание паттернов проектирования

 

При описании паттернов проектировании мы будем придерживаться единого принципа. Описание каждого паттерна разбито на разделы, перечисленные ниже.

Такой подход позволяет единообразно представить информацию, облегчает изучение, сравнение и применение паттернов.

 

Название и классификация паттерна

Название паттерна должно четко отражать его назначение.

 

Назначение

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

 

Известен также под именем

Другие распространенные названия паттерна, если таковые имеются.

Мотивация

Сценарий, иллюстрирующий задачу проектирования и то, как она решается данной структурой класса или объекта. Благодаря мотивации можно лучше понять последующее, более абстрактное описание паттерна.

 

Описание паттернов проектирования

Применимость

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

Структура

Графическое представление классов в паттерне с использованием нотации, основанной на методике Object Modeling Technique (OMT) [RBP+91]. Мы пользуемся также диаграммами взаимодействий [JCJO92, Воо94] для иллюстрации последовательностей запросов и отношений между объектами. В приложении В эта нотация описывается подробно.

Участники

Классы или объекты, задействованные в данном паттерне проектирования, и их функции.

Отношения

Взаимодействие участников для выполнения своих функций.

Результаты

Насколько паттернудовлетворяет поставленным требованиям? Результаты

применения, компромиссы, на которые приходится идти. Какие аспекты поведения системы можно независимо изменять, используя данный паттерн?

Реализация

Сложности и так называемые подводные камни при реализации паттерна.

Советы и рекомендуемые приемы. Есть ли у данного паттерна зависимость от языка программирования?

Пример кода

Фрагмент кода, иллюстрирующий вероятную реализацию на языках C++ или Smalltalk.

Известные применения

Возможности применения паттерна в реальных системах. Даются, по меньшей мере, два примера из различных областей.

Родственные паттерны

Связь других паттернов проектирования с данным. Важные различия. Использование данного паттерна в сочетании с другими.

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

 

Организация каталога

Паттерны проектирования различаются степенью детализации и уровнем абстракции и должны быть каким-то образом организованы.

Мы будем классифицировать паттерны по двум критериям (табл. 1.1). Первый - цель - отражает назначение паттерна. В связи с этим выделяются порождающие паттерны, структурные паттерны и паттерны поведения. Первые связаны с процессом создания объектов. Вторые имеют отношение к композиции объектов и классов. Паттерны поведения характеризуют то, как классы или объекты взаимодействуют между собой.

 

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

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

Порождающие паттерны классов частично делегируют ответственность за создание объектов своим подклассам, тогда как порождающие паттерны объектов передают ответственность другому объекту. Структурные паттерны классов используют наследование для составления классов, в то время как структурные паттерны объектов описывают способы сборки объектов из частей. Поведенческие паттерны классов используют наследование для описания алгоритмов и потока управления, а поведенческие паттерны объектов описывают, как объекты, принадлежащие некоторой группе, совместно функционируют и выполняют задачу, которая ни одному отдельному объекту не под силу.

 

 

Диаграммы классов

Мы пользуемся тремя видами диаграмм:

• а на диаграмме классов отображены классы, их структура и статические отношения между ними;

а на диаграмме объектов показана структура объектов во время выполнения;

а на диаграмме взаимодействий изображен поток запросов между объектами.

В описании каждого паттерна проектирования есть хотя бы одна диаграмма классов. Остальные используются, если в них возникает необходимость. Диаграммы классов и объектов основаны на методологии ОМТ (Object Modeling Technique - методика моделирования объектов) [RBP+91, Rum94].' Диаграммы взаимодействий заимствованы из методологии Objectory [JCJO92] и метода Буча[Воо94].

В.1. Диаграмма классов

На рисунке B.la представлена нотация ОМТ для абстрактных и конкретных классов. Класс обозначается прямоугольником, в верхней части которого жирным шрифтом напечатано имя класса. Основные операции класса перечисляются под именем класса. Все переменные экземпляра находятся ниже операций. Информация о типе необязательна; мы пользуемся синтаксисом C++, ставя имя типа перед именем операции (для обозначения типа возвращаемого значения), переменной экземпляра или фактического параметра. Курсив служит указанием на то, что класс или операция абстрактны.

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

Бледный шрифт клиента напоминает также о том, что мы специально не включили клиента в состав участников.

На рисунке В. 1с показаны отношения между классами. В нотации ОМТ для обозначения наследования классов используется треугольник, направленный от

подкласса (на рисунке - LineShape) к родительскому классу (Shape). Ссылка на объект, представляющая отношение агрегирования «является частью», обозначается линией со стрелкой с ромбиком на конце. Стрелка указывает на агрегируемый класс (например, Shape). Линия со стрелкой без ромбика обозначает отношение осведомленности (так, LineShape содержит ссылку на объект Color, который может использоваться также и другими фигурами). Рядом с началом стрелки может находиться еще и имя ссылки, позволяющее отличить ее от других ссылок.1

Еще одно полезное свойство, которое следует визуализировать, - то, какие классы создают экземпляры других классов. Для этого используется пунктирная линия, поскольку ОМТ такого отношения не поддерживает. Мы называем такое отношение «создает». Стрелка направлена в сторону класса, экземпляр которого инстанцируется. На рисунке В. 1с класс GreationTool создает объекты класса LineShape.

В ОМТ определен также символ залитого круга, обозначающий «более одного». Если такой кружок появляется рядом со стрелкой, то он говорит о том, что она ссылается на несколько объектов или что несколько объектов агрегируются.

На рисунке В. 1с показано, что класс Drawing агрегирует несколько объектов типа Shape.

Наконец, мы дополнили ОМТ аннотациями на псевдокоде, которые позволяют коротко описать реализацию операций. На рисунке В. Id приведена такая аннотация для операции Draw в классе Drawing.

В.2. Диаграмма объектов

На диаграмме объектов представлены только экземпляры. На ней показан мгновенный снимок объектов в паттерне проектирования. Объекты именуются «aSomething», где Something - это класс объекта. Для обозначения объекта используется прямоугольник с закругленными углами (что несколько отличается от стандарта ОМТ), в котором имя объекта отделено от ссылок на другие объекты горизонтальной линией. Стрелки ведут к объектам, на которые ссылается данный.

На рисунке В.2 приведен соответствующий пример.

Рис. В.2. Нотация диаграмм объектов

В.З. Диаграмма взаимодействий

Порядок исполнения запросов, которые объекты посылают друг другу, показан на диаграмме взаимодействий. Так, на рисунке В.З представлено, как фигура добавляется к рисунку.

 

Диаграмма взаимодействий

На диаграмме взаимодействий время откладывается сверху вниз. Сплошная вертикальная линия обозначает время жизни объекта. Соглашение об именовании объектов такое же, как на диаграммах объектов: имени класса предшествует буква «а» (например, aShape). Если объект еще не создан к начальному моменту времени, представленному на диаграмме, то его вертикальная линия идет пунктиром вплоть до момента создания.

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

Имя запроса показывается над стрелкой. Запрос на создание объекта представлен пунктирной линией со стрелкой. Запрос объекта-отправителя самому себе изображается стрелкой, указывающей на сам этот объект. На рисунке В.З видно, что первый запрос, исходящий от aCreationTool, преследует целью создание объекта aLineShape. Затем aLineShape добавляется к объекту aDrawing с помощью операции Add, после чего aDrawing посылает самому себе запрос на обновление Refresh. Отметим, что частью операции Refresh является посылка объектом aDrawing запроса к aLineShape.