- •197110, Санкт-Петербург, Чкаловский пр., 15.
- •Глава 1. Введение в паттерны проектирования 15
- •Глава 2. Проектирование редактора документов 39
- •Глава 3. Порождающие паттерны 75
- •Глава 4. Структурные паттерны 109
- •Глава 5. Паттерны поведения 173
- •Глава 6. Заключение 271
- •Предисловие
- •Глава 1. Введение в паттерны проектирования
- •1.1. Что такое паттерн проектирования
- •1.2. Паттерны проектирования в схеме mvc в языке Smalltalk
- •1.3. Описание паттернов проектирования
- •1.4. Каталог паттернов проектирования
- •1.5. Организация каталога
- •1.6. Как решать задачи проектирования с помощью паттернов
- •Поиск подходящих объектов
- •Определение степени детализации объекта
- •Специфицирование интерфейсов объекта
- •Специфицирование реализации объектов
- •Механизмы повторного использования
- •Сравнение структур времени выполнения и времени компиляции
- •Проектирование с учетом будущих изменений
- •1.7. Как выбирать паттерн проектирования
- •1.8. Как пользоваться паттерном проектирования
- •Глава 2. Проектирование редактора документов
- •2.1. Задачи проектирования
- •2.2. Структура документа
- •Рекурсивная композиция
- •Паттерн компоновщик
- •2.3. Форматирование
- •Инкапсуляция алгоритма форматирования
- •Классы Compositor и Composition
- •Стратегия
- •2.4. Оформление пользовательского интерфейса
- •Прозрачное обрамление
- •Моноглиф
- •Паттерн декоратор
- •2.5. Поддержка нескольких стандартов внешнего облика
- •Абстрагирование создания объекта
- •Фабрики и изготовленные классы
- •Паттерн абстрактная фабрика
- •2.6. Поддержка нескольких оконных систем
- •Можно ли воспользоваться абстрактной фабрикой?
- •Инкапсуляция зависимостей от реализации
- •Классы Window и WindowImp
- •Подклассы WindowImp
- •Конфигурирование класса Window с помощью WindowImp
- •Паттерн мост
- •2.7. Операции пользователя
- •Инкапсуляция запроса
- •Класс Command и его подклассы
- •Отмена операций
- •История команд
- •Паттерн команда
- •2.8. Проверка правописания и расстановка переносов
- •Доступ к распределенной информации
- •Инкапсуляция доступа и порядка обхода
- •Класс Iterator и его подклассы
- •Паттерн итератор
- •Обход, и действия выполняемые при обходе
- •Класс Visitor и его подклассы
- •Паттерн посетитель
- •2.9. Резюме
- •Глава 3. Порождающие паттерны
- •Паттерн Abstract Factory
- •Паттерн Builder
- •Паттерн Factory Method
- •Паттерн Prototype
- •Паттерн Singleton
- •Обсуждение порождающих паттернов
- •Глава 4. Структурные паттерны
- •Паттерн Adapter
- •Паттерн Bridge
- •Паттерн Composite
- •Паттерн Decorator
- •Паттерн Facade
- •Паттерн Flyweight
- •Паттерн Proxy
- •Обсуждение структурных паттернов
- •Адаптер и мост
- •Компоновщик, декоратор и заместитель
- •Глава 5. Паттерны поведения
- •Паттерн Chain of Responsibility
- •Паттерн Command
- •Паттерн Interpreter
- •Паттерн Iterator
- •Паттерн Mediator
- •Паттерн Memento
- •Паттерн Observer
- •Паттерн State
- •Паттерн Strategy
- •Паттерн Template Method
- •Паттерн Visitor
- •Обсуждение паттернов поведения Инкапсуляция вариаций
- •Объекты как аргументы
- •Должен ли обмен информацией быть инкапсулированным или распределенным
- •Разделение получателей и отправителей
- •Глава 6. Заключение
- •6.1. Чего ожидать от паттернов проектирования
- •Единый словарь проектирования
- •Помощь при документировании и изучении
- •Дополнение существующих методов
- •Цель реорганизации
- •6.2. Краткая история
- •6.3. Проектировщики паттернов
- •Языки паттернов Александра
- •Паттерны в программном обеспечении
- •6.4. Приглашение
- •6.5. На прощание
- •Приложение а. Глоссарий
- •Приложение в. Объяснение нотации
- •В.1. Диаграмма классов
- •В.2. Диаграмма объектов
- •В.3. Диаграмма взаимодействий
- •Приложение с. Базовые классы
- •Библиография
- •Алфавитный указатель
Приложение в. Объяснение нотации
На протяжении всей книги мы пользуемся диаграммами для иллюстрации важных идей. Некоторые диаграммы нестандартны: например, снимок экрана, где изображено диалоговое окно, или схематичное изображение дерева объектов. Но при описании паттернов проектирования для обозначения отношений и взаимодействий между классами и объектами применяется более формальная нотация. В настоящем приложении эта нотация рассматривается подробно. Мы пользуемся тремя видами диаграмм:
на диаграмме классов отображены классы, их структура и статические отношения между ними;
на диаграмме объектов показана структура объектов во время выполнения;
на диаграмме взаимодействий изображен поток запросов между объектами.
В описании каждого паттерна проектирования есть хотя бы одна диаграмма классов. Остальные используются, если в них возникает необходимость. Диаграммы классов и объектов основаны на методологии OMT (Object Modeling Technique – методика моделирования объектов) [RBP+91, Rum94]35. Диаграммы взаимодействий заимствованы из методологии Objectory (JCJO92] и метода Буча [Boo94].
В.1. Диаграмма классов
На рисунке В.1а представлена нотация OMT для абстрактных и конкретных классов. Класс обозначается прямоугольником, в верхней части которого жирным шрифтом напечатано имя класса. Основные операции класса перечисляются под именем класса. Все переменные экземпляра находятся ниже операций. Информация о типе необязательна; мы пользуемся синтаксисом C++, ставя имя типа перед именем операции (для обозначения типа возвращаемого значения), переменной экземпляра или фактического параметра. Курсив служит указанием на то, что класс или операция абстрактны.
При использовании некоторых паттернов проектирования полезно видеть, где классы клиентов ссылаются на классы-участники. Если паттерн включает класс клиента в качестве одного из участников (это означает, что на клиента возлагаются определенные функции), то клиент изображается как обычный класс. Так, например, обстоит дело в паттерне приспособленец. Если же клиент не входит в состав участников паттерна (то есть не несет никаких обязанностей), то его изображение все равно полезно, поскольку проясняет способ взаимодействия участников с клиентами. В этом случае классы клиентов изображаются бледным шрифтом, как показано на рисунке В.1б. Примером может служить паттерн заместитель. Бледный шрифт клиента напоминает также о том, что мы специально не включили клиента в состав участников.
На рисунке В.1в показаны отношения между классами. В нотации OMT для обозначения наследования классов используется треугольник, направленный от подкласса (на рисунке – LineShape) к родительскому классу (Shape). Ссылка на объект, представляющая отношение агрегирования «является частью», обозначается линией со стрелкой с ромбиком на конце. Стрелка указывает на агрегируемый класс (например, Shape). Линия со стрелкой без ромбика обозначает отношение осведомленности (так, LineShape содержит ссылку на объект Color, который может использоваться также и другими фигурами). Рядом с началом стрелки может находиться еще и имя ссылки, позволяющее отличить ее от других ссылок36.
Еще одно полезное свойство, которое следует визуализировать, – то, какие классы создают экземпляры других классов. Для этого используется пунктирная линия, поскольку OMT такого отношения не поддерживает. Мы называем такое отношение «создает». Стрелка направлена в сторону класса, экземпляр которого инстанцируется. На рисунке В.1в класс CreationTool создает объекты класса LineShape.
В OMT определен также символ залитого круга, обозначающий «более одного». Если такой кружок появляется рядом со стрелкой, то он говорит о том, что она ссылается на несколько объектов или что несколько объектов агрегируются. На рисунке В.1в показано, что класс Drawing агрегирует несколько объектов типа Shape.
Наконец, мы дополнили OMT аннотациями на псевдокоде, которые позволяют коротко описать реализацию операций. На рисунке В.1г приведена такая аннотация для операции Draw в классе Drawing.