- •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. Диаграмма взаимодействий
- •Приложение с. Базовые классы
- •Библиография
- •Алфавитный указатель
6.5. На прощание
В лучших проектах используется много паттернов проектирования. Единое целое образуется в результате их согласованных взаимных действий. Вот что говорит об этом Кристофер Александр: «Можно строить здания, нанизывая паттерны в достаточно произвольном порядке. Такое здание будет просто собранием паттернов. В нем нет плотности. Нет основательности. Но можно объединять паттерны и так, что в одном и том же физическом объеме они будут перекрывать друг друга. Тогда здание получается очень плотным, в небольшом пространстве сосредотачивается много функций. За счет такой плотности здание приобретает основательность.» (A Pattern Language [AIS+77, стр. xli]).
Приложение а. Глоссарий
Абстрактная операция – операция, которая объявляет сигнатуру, но не реализует ее. В C++ абстрактные операции соответствуют исключительно виртуальным функциям-членам.
Абстрактная связанность – говорят, что класс А абстрактно связан с абстрактным классом В, если в А есть ссылка на В. Такое отношение мы называем абстрактной связанностью, поскольку А ссылается на тип объекта, а не на конкретный объект.
Абстрактный класс – класс, единственным назначением которого является определение интерфейса. Абстрактный класс полностью или частично делегирует свою реализацию подклассам. Создавать экземпляры абстрактного класса нельзя.
Агрегированный объект – объект, составленный из подобъектов. Подобъекты называются частями агрегата, и агрегат отвечает за них.
Делегирование – механизм реализации, при котором объект перенаправляет или делегирует запрос другому объекту (уполномоченному). Уполномоченный выполняет запрос от имени исходного объекта.
Деструктор – в C++ это операция, которая автоматически вызывается для очистки объекта непосредственно перед его удалением.
Диаграмма взаимодействий – диаграмма, на которой показан поток запросов между объектами.
Диаграмма классов – диаграмма, на которой изображены классы, их внутренняя структура и операции, а также статические связи между ними.
Диаграмма объекта – диаграмма, на которой изображена структура конкретного объекта во время выполнения.
Динамическое связывание – ассоциация между запросом к объекту и одной из его операций, устанавливаемая во время выполнения. В C++ динамически связываться могут только виртуальные функции.
Дружественный класс – в C++: класс, обладающий теми же правами доступа к операциям и данным некоторого класса, что и сам этот класс.
Закрытое наследование – в C++: класс, наследуемый только ради реализации.
Замещение – переопределение операции, унаследованной от родительского класса, в подклассе.
Инкапсуляция – результат сокрытия представления и реализации в объекте. Представление невидимо и недоступно извне. Получить доступ к представлению объекта и модифицировать его можно только с помощью операций.
Инструментальная библиотека (toolkit) – набор классов, обеспечивающих полезную функциональность, но не определяющих дизайн приложения.
Интерфейс – набор всех сигнатур, определенных операциями объекта. Интерфейс описывает множество запросов, на которые может отвечать объект.
Каркас – набор взаимодействующих классов, описывающих повторно применимый дизайн некоторой категории программ. Каркас задет архитектуру приложения, разбивая его на отдельные классы с четко определенными функциями и взаимодействиями. Разработчик настраивает каркас под конкретное приложение путем порождения подклассов и составления композиций из объектов, принадлежащих классам каркаса.
Класс – определяет интерфейс и реализацию объекта. Описывает внутреннее представление и операции, которые объект может выполнять.
Композиция объектов – объединение нескольких объектов для получения более сложного поведения.
Конкретный класс – класс, в котором нет абстрактных операций. Может иметь экземпляры.
Конструктор – в C++: операция, автоматически вызывающаяся для инициализации новых экземпляров.
Метакласс – в Smalltalk классы являются объектами. Метакласс – это класс объекта-класса.
Наследование – отношение, которое определяет одну сущность в терминах другой. В случае наследования класса новый класс определяется в терминах одного или нескольких родительских классов. Новый класс наследует интерфейс и реализацию от своих родителей. Новый класс называется подклассом или производным классом (в C++). Наследование класса объединяет наследование интерфейса и наследование реализации. В случае наследования интерфейса новый интерфейс определяется в терминах одного или нескольких существующих. При наследовании реализации новая реализация определяется в терминах одной или нескольких существующих.
Объект – имеющаяся во время выполнения сущность, в которой хранятся данные и процедуры для работы с ними.
Операция – на данные объекта можно воздействовать только с помощью его операций. Объект выполняет операцию, когда получает запрос. В C++ операции называются функциями-членами, в Smalltalk – методами.
Операция класса – операция, определенная для класса в целом, а не для индивидуального объекта. В C++ операции класса называются статическими функциями-членами.
Отношение агрегирования – отношение агрегата и его частей. Класс определяет такое отношение для своих экземпляров, то есть агрегированных объектов.
Отношение осведомленности – говорят, что одному классу известно о другом, если первый ссылается на второй.
Параметризованный тип – тип, где некоторые составляющие типы оставлены неопределенными. Они передаются как параметры в точке использования. В C++ параметризованные типы называются шаблонами.
Паттерн проектирования – паттерн проектирования именует, мотивирует и объясняет конкретный прием проектирования, который относится к задаче, часто возникающей при работе над объектно-ориентированными системами. Паттерн описывает задачу, ее решение, область применимости этого решения и его результаты. Он также содержит рекомендации по реализации и примеры. Под решением понимается схема организации объектов и классов, позволяющая справиться с проблемой. Паттерн адаптируется для работы в конкретных условиях и реализуется в заданном контексте.
Переменная экземпляра – элемент данных, определяющий часть представления объекта. В C++ используется термин данные-член.
Подкласс – класс, наследующий другому классу. В C++ подкласс называется производным классом.
Подмешанный класс – класс, спроектированный так, чтобы сочетаться с другими классами путем наследования. Подмешанные классы обычно абстрактны.
Подсистема – независимая группа классов, функционирующих совместно для выполнения набора обязанностей.
Подтип – один тип называется подтипом другого, если интерфейс первого содержит интерфейс второго.
Полиморфизм – способность подставлять во время выполнения вместо одного объекта другой с совместимым интерфейсом.
Получатель – объект, которому направлен запрос.
Прозрачный ящик как способ повторного использования – стиль повторного использования, основанный на наследовании классов. Подкласс повторно использует интерфейс и реализацию родительского класса, но может также иметь доступ к закрытым для других аспектам своего родителя.
Протокол – расширяет концепцию интерфейса за счет включения допустимой последовательности запросов.
Родительский класс – класс, которому наследует другой класс. Синонимы –суперкласс (Smalltalk), базовый класс (C++) и класс-предок.
Связанность – степень зависимости компонентов программы друг от друга.
Сигнатура – под сигнатурой операции понимается сочетание ее имени, параметров и возвращаемого значения.
Ссылка на объект – значение, которое идентифицирует другой объект.
Супертип – тип родителя, которому наследует данный тип.
Тип – имя конкретного интерфейса.
Черный ящик как способ повторного использования – стиль повторного использования, основанный на композиции объектов. Объекты-компоненты не раскрывают Друг другу деталей своего внутреннего устройства и потому могут быть уподоблены черным ящикам.