- •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. Диаграмма взаимодействий
- •Приложение с. Базовые классы
- •Библиография
- •Алфавитный указатель
Алфавитный указатель
А
Абстрактная фабрика 21, 87
другое имя 87
известные применения 94
мотивация 87
назначение 87
отношения 89
применимость 88
пример кода 91
реализация 90
результаты 89
родственные паттерны 95
структура 88
участники 89
Абстрактные
класс 28, 315
объект 315
операция 315
связанность 315
Агрегирование 34
Адаптер 21, 130
другое имя 130
и мост 196
известные применения 139
мотивация 130
назначение 130
отношения 132
пример кода 136
применимость 131
реализация 134
родственные паттерны 140
результаты 132
структура 132
участники 132
В
Вид 18
Выбор языка программирования 17
Г
Глиф 47
Д
Декоратор 21, 159
другое имя 159
и заместитель 196
и компоновщик 196
известные применения 166
мотивация 159
назначение 159
отношения 162
применимость 161
пример кода 164
реализация 163
результаты 162
родственные паттерны 167
структура 161
участники 161
Делегирование 32, 315
Деструктор 315
Диаграммы
взаимодействий 315, 322
классов 315, 320
объектов 315, 321
Динамическое связывание 315
Дружественный класс 315
З
Задача 16
Закрытое наследование 315
Заместитель 22, 186
другое имя 186
и декоратор 196
известные применения 192
мотивация 186
назначение 186
отношения 189
применимость 188
пример кода 192
реализация 190
результаты 189
родственные паттерны 192
структура 188
участники 189
Замещение 315
Запрос 25
И
Известные применения паттерна 20
Имя 16
Инкапсуляция 25, 315
вариаций 302
Инстанцирование 27
Инструментальная библиотека 37, 315
Интерпретатор 22, 218
известные применения 229
мотивация 218
назначение 218
отношения 221
применимость 220
пример кода 222
реализация 222
результаты 221
родственные паттерны 229
структура 220
участники 220
Интерфейс 26, 315
идентичный 30
наследование 29
специфицирование 26
Итератор 22, 229
другое имя 229
известные применения 242
мотивация 229
назначение 229
отношения 232
применимость 231
пример кода 235
реализация 232
результаты 232
родственные паттерны 242
структура 231
участники 232
К
Каркас 37, 315
Каталог
организация 23
паттернов 21
Классификация паттерна 19
Класс 315
Glyph 47
абстрактный 28
глиф 47
конкретный 28
наследование 28, 28
подкласс 28
подмешанный 28
родительский 28
экземпляр 27
Клиент 25
Команда 21, 208
другое имя 209
известные применения 217
мотивация 209
назначение 208
отношения 212
применимость 211
пример кода 214
реализация 213
результаты 213
родственные паттерны 218
структура 212
участники 212
Композиция
объектов 31, 315
рекурсивная 46
Компоновщик 21, 149
и декоратор 196
известные применения 158
мотивация 149
назначение 149
отношения 152
применимость 150
пример кода 156
реализация 152
результаты 152
родственные паттерны 159
структура 151
участники 151
Конкретный класс 28, 315
Конструктор 316
Контроллер 18
М
Метакласс 316
Метод 25
Модель 18
Модель/вид/контроллер 17
Мост 21, 140
другое имя 140
и адаптер 196
известные применения 148
мотивация 140
назначение 140
отношения 143
применимость 142
пример кода 145
реализация 143
результаты 143
родственные паттерны 149
структура 142
участники 142
Мотивация паттерна 20
Н
Наблюдатель 22, 259
другие имена 259
известные применения 268
мотивация 259
назначение 259
отношения 261
применимость 260
пример кода 265
реализация 262
результаты 261
родственные паттерны 268
структура 260
участники 260
Название 19
Назначение 19
Наследование 28, 316
интерфейса 29
класса 29
О
Объединение функциональности 61
Объект 25, 316
как аргумент 302
композиция 31
определение степени детализации 26
разложение системы 25
специфицирование
интерфейсов 26
реализации 27
уполномоченные 32
Одиночка 22, 121
известные применения 127
мотивация 121
назначение 121
отношения 122
применимость 121
пример кода 125
реализация 122
результаты 122
родственные паттерны 127
структура 121
участники 121
Операции 25, 316
замещение 28
сигнатура 26
Описание 19
Организация каталога 23
Осведомленность 34
Отношения
агрегирования 316
осведомленности 316
паттерна 20
Отправители и получатели 303
П
Параметризованные типы 33, 316
Паттерны 17
Abstract Factory. См. Абстрактная
фабрика
Adapter. См. Адаптер
Bridge. См. Мост
Builder. См. Строитель
Chain of Responsibility. См. Цепочка
обязанностей
Command. См. Команда
Composite. См. Компоновщик
Decorator. См. Декоратор
Facade. См. Фасад
Factory Method. См. Фабричный метод
Flyweight. См. Приспособленец
Interpreter. См. Интерпретатор
Iterator. См. Итератор
Mediator. См. Посредник
Memento. См. Хранитель
Observer. См. Наблюдатель
Prototype. См. Прототип
Proxy. См. Заместитель
Singleton. См. Одиночка
State. См. Состояние
Strategy. См. Стратегия
Template Method. См. Шаблонный метод
Visitor. См. Посетитель
в схеме MVC 17
выбор языка 17
задача 16
известен также под именем 19
известные применения 20
имя 16
использование 40
каталог 21
классификация 19
критерии 23
мотивация 20
название 19
назначение 19
описание 19
отношения 20
поведения 199
порождающие 83
применимость 20
пример кода 20
проектирования 316
реализация 20
результаты 17, 20
решение 16
родственные 20
структура 20
структурные 129
уровень 23
участники 20
цель 23
Переменная экземпляра 27, 316
Пересечение функциональности 60
Подкласс 28, 316
Подмешанный класс 28, 316
Подсистема 316
Подтип 316
Полиморфизм 316
Получатель 316
и отправитель 303
Посетитель 23, 289
известные применения 301
мотивация 290
назначение 290
отношения 293
применимость 292
пример кода 297
реализация 295
результаты 293
родственные паттерны 302
структура 292
участники 292
Посредник 22, 242
известные применения 250
мотивация 243
назначение 243
отношения 246
применимость 245
пример кода 247
реализация 247
результаты 246
родственные паттерны 251
структура 245
участники 246
Применимость 20
Пример кода 20
Приспособленец 22, 176
известные применения 185
мотивация 176
назначение 176
отношения 180
применимость 178
пример кода 181
реализация 180
результаты 180
родственные паттерны 186
структура 179
участники 179
Прозрачный ящик 31, 316
Протокол 316
Прототип 22, 112
известные применения 120
мотивация 112
назначение 112
отношения 114
применимость 114
пример кода 117
реализация 116
результаты 114
родственные паттерны 120
структура 114
участники 114
Р
Реализация 20
Редактор Lexi 43
Compositor 50
абстрактная фабрика 59
анализ 76
внешний облик 56
глифы 47
декоратор 55
документ 45
доступ к информации 71
зависимость от реализации 60
задачи проектирования 43
инкапсуляция запроса 66
история команд 69
итератор 75
классы
Command 67
Iterator 72
Visitor 79
Window 61
команда 70
компоновщик 49
моноглиф 53
мост 65
оконные системы 59
операции пользователя 66
отмена операций 68
пользовательский интерфейс 52
порядок обхода 71
посетитель 80
проверка правописания 70
расстановка переносов 70
создание объектов 56
стратегия 52
фабрики 57
форматирование 49
Результаты 17, 20
Рекурсивная композиция 46
Решение 16
Родительский класс 28, 317
Родственные паттерны 20
С
Связанность 317
Сигнатура 317
операции 26
Сообщение 25
Состояние 22, 268
известные применения 276
мотивация 268
назначение 268
отношения 270
применимость 268
пример кода 272
реализация 271
результаты 270
родственные паттерны 276
структура 270
участники 270
Ссылка на объект 317
Стратегия 22, 277
другое имя 277
известные применения 284
мотивация 277
назначение 277
отношения 279
применимость 278
пример кода 281
реализация 280
результаты 278
родственные паттерны 285
структура 278
участники 278
Строитель 21, 95
известные применения 102
мотивация 95
назначение 95
отношения 97
применимость 96
пример кода 99
реализация 98
результаты 98
родственные паттерны 103
структура 96
участники 97
Структура 20
Супертип 317
Схемы
Model/View/Controller 18
MVC 18
модель/вид/контроллер 18
Т
Тип 26, 317
параметризованный 33, 316
У
Участники 20
Уполномоченный 32
Ф
Фабричный метод 21, 103
другое имя 103
известные применения 111
мотивация 103
назначение 103
отношения 105
применимость 104
пример кода 110
реализация 107
результаты 105
родственные паттерны 112
структура 105
участники 105
Фасад 21, 168
известные применения 174
мотивация 168
назначение 168
отношения 170
применимость 169
пример кода 171
реализация 171
результаты 170
родственные паттерны 175
структура 170
участники 170
Функциональность
объединение 61
пересечение 60
Х
Хранитель 22, 251
другое имя 251
известные применения 257
мотивация 251
назначение 251
отношения 253
применимость 253
пример кода 255
реализация 254
результаты 254
родственные паттерны 258
структура 253
участники 253
Ц
Цепочка обязанностей 21, 199
известные применения 208
мотивация 200
назначение 200
отношения 202
применимость 201
пример кода 205
реализация 203
результаты 202
родственные паттерны 208
структура 202
участники 202
Ч
Черный ящик 31, 317
Ш
Шаблонный метод 22, 285
известные применения 289
мотивация 285
назначение 285
отношения 287
применимость 286
пример кода 289
реализация 288
результаты 287
родственные паттерны 289
структура 287
участники 287
Э
Экземпляр класса 27
Я
Ящик
прозрачный 31, 316
черный 31, 317
A
Abstract Factory. См. Абстрактная фабрика
абстрактная фабрика 89
AbstractClass
шаблонный класс 287
AbstractExpression
интерпретатор 220
AbstractProduct
абстрактная фабрика 89
Abstraction
мост 142
Action 209
Adaptee
адаптер 132
Adapter. См. Адаптер
адаптер 132
Aggregate
итератор 232
B
Bridge. См. Мост
Builder. См. Строитель
строитель 97
C
Caretaker
хранитель 253
Chain of Responsibility. См. Цепочка
Обязанностей
Client
абстрактная фабрика 89
адаптер 132
интерпретатор 221
команда 212
компоновщик 151
приспособленец 180
прототип 114
цепочка обязанностей 202
Colleague
посредник 246
Command. См. Команда
команда 212
Component
декоратор 161
компоновщик 151
Composite. См. Компоновщик
компоновщик 151
ConcreteAggregate
итератор 232
ConcreteBuilder
строитель 97
ConcreteClass
шаблонный класс 287
ConcreteCommand
команда 212
ConcreteComponent
декоратор 161
ConcreteCreator
фабричный метод 105
ConcreteDecorator
декоратор 162
ConcreteElement
посетитель 293
ConcreteFactory
абстрактная фабрика 89
ConcreteFlyweight
приспособленец 179
ConcreteHandler
цепочка обязанностей 202
ConcreteImplementor
мост 143
ConcreteIterator
итератор 232
ConcreteMediator
посредник 246
ConcreteObserver
наблюдатель 261
ConcteteProduct
абстрактная фабрика 89
фабричный метод 105
ConcretePrototype
прототип 114
ConcreteState
состояние 270
ConcreteStrategy
стратегия 278
ConcreteSubject
наблюдатель 261
ConcreteVisitor
посетитель 293
Context
интерпретатор 221
состояние 270
стратегия 279
Creator
фабричный метод 105
Cursor 229
D
Decorator. См. Декоратор
декоратор 161
Dependents 259
Director
строитель 97
E
Element
посетитель 293
F
Facade. См. Фасад
фасад 170
Factory Method. См. Фабричный метод
Flyweight. См. Приспособленец
приспособленец 179
FlyweightFactory
приспособленец 179
G
Glyph 47
H
Handle/Body 140
Handler
цепочка обязанностей 202
I
Implementor
мост 143
Interpreter. См. Интерпретатор
Invoker
команда 212
Iterator. См. Итератор
итератор 232
K
Kit 87
L
Leaf
компоновщик 151
Lexi. См. Редактор Lexi
List 323
ListIterator 325
M
Mediator. См. Посредник
посредник 246
Memento. См. Хранитель
хранитель 253
Model/View/Controller 18
MVC 18
N
NonterminalExpression
интерпретатор 220
O
ObjectStructure
посетитель 293
Observer. См. Наблюдатель
наблюдатель 260
Originator
хранитель 253
P
Point 325
Policy 277
Product
строитель 97
фабричный метод 105
Prototype. См. Прототип
прототип 114
Proxy. См. Заместитель
заместитель 189
Publish-Subscribe 259
R
RealSubject
заместитель 189
Receiver
команда 212
Rect 326
RefinedAbstraction
мост 143
S
Singleton. См. Одиночка
одиночка 121
State. См. Состояние
состояние 270
Strategy. См. Стратегия
стратегия 278
Subject
заместитель 189
наблюдатель 260
Surrogate 186
T
Target
адаптер 132
Template Method. См. Шаблонный метод
TerminalExpression
интерпретатор 220
Token 251
Toolkit 315
Transaction 209
U
UnsharedConcreteFlyweight
приспособленец 179
V
Virtual Constructor 103
Visitor. См. Посетитель
посетитель 292
W
Wrapper 130, 159
1 Дизайн Lexi основан на программе Doc - текстового редактора, разработанного Кальдером [CL92].
2 Авторы часто рассматривают документы и в терминах их логической структуры: предложений, абзацев, разделов, подразделов и глав. Чтобы не слишком усложнять пример, мы не будем явно хранить во внутреннем представлении информацию о логической структуре. Vol_2005 Но то проектное решение, которое мы опишем, вполне пригодно для представления и такой информации.
3 Впервые термин «глиф» в этом контексте употребил Пол Кальдер [CL90]. В большинстве современных редакторов документов отдельные символы не представляются объектами, скорее всего, из соображений эффективности. Кальдер продемонстрировал практическую пригодность этого подхода в своей диссертации [Ca193]. Наши глифы проще предложенных им, поскольку мы для простоты ограничились строгими иерархиями. Глифы Кальдера могут использоваться совместно для уменьшения потребления памяти и, стало быть, образуют направленные ациклические графы. Для достижения того же эффекта мы можем воспользоваться паттерном приспособленец, но оставим это в качестве упражнения читателю.
4 Представленный здесь интерфейс намеренно сделан минимальным, чтобы не загромождать обсуждение техническими деталями. Полный интерфейс должен бы включать операции для работы с графическими атрибутами: цветами, шрифтами и преобразованиями координат, а также операции для более развитого управления потомками.
5 Возможно, целочисленный индекс - не лучший способ описания потомков глифа. Это зависит от структуры данных, используемой внутри глифа. Если потомки хранятся в связанном списке, то более эффективно было бы передавать указатель на элемент списка. Мы еще увидим более удачное решение проблемы индексации в разделе 2.8, когда будем обсуждать анализ документа.
6 У пользователя найдется что сказать и по поводу логической структуры документа: предложений, абзацев, разделов, глав и т.д. Физическая структура в общем-то менее интересна. Большинству людей не важно, где в абзаце произошел разрыв строки, если в целом все отформатировано правильно. То же самое относится и к форматированию колонок и страниц. Таким образом, пользователи задают только высокоуровневые ограничения на физическую структуру, a Lexi выполняет их.
7 Композитор должен получить коды символов глифов Character, чтобы вычислить места разбиения на строки. В разделе 2.8 мы увидим, как можно получить информацию полиморфно, не добавляя специфичной для символов операции к интерфейсу класса Glyph.
8 Под повтором (redo) понимается выполнение только что отмененной операции.
9 Концептуально клиентом является пользователь Lexi, но на самом деле это просто какой-то другой объект (например, диспетчер событий), который управляет обработкой ввода пользователя.
10 Мы могли бы воспользоваться перегрузкой функций, чтобы присвоить этим функциям-членам одинаковые имена, поскольку их можно различить по типам параметров. Здесь мы дали им разные имена, чтобы было видно, что это все-таки разные функции, особенно при их вызове.
11 Функция IsMisspelled реализует алгоритм проверки орфографии, детали которого мы здесь не приводим, поскольку мы сделали его независимым от дизайна Lexi. Мы можем поддержать разные алгоритмы, порождая подклассы класса SpellingChecker. Или применить для этой цели паттерн стратегия (как для форматирования в разделе 2.3).
12 «Посетить» - это лишь немногим более общее слово, чем «проанализировать». Оно просто предвосхищает ту терминологию, которой мы будем пользоваться при обсуждении следующего паттерна.
13 Для таких приложений характерны паттерны компоновщик и декоратор.
14 CreateManipulator - это пример фабричного метода.
15 Очень легко забыть об удалении итератора после завершения работы с ним. При обсуждении паттерна итератор рассказано, как защититься от таких ошибок.
16 Время поиска в этой схеме пропорционально частоте смены шрифта. Наименьшая производительность бывает, когда смена шрифта происходит на каждом символе, но на практике это бывает редко.
17 В приведенном выше примере кода информация о стиле вынесена наружу, так что внутреннее состояние - это только код символа.
18 Другой подход к обеспечению независимости от внешнего облика см. в описании паттерна абстрактная фабрика.
19 Эта техника используется при реализации распределенных объектов в системе NEXTSTEP [Add94] (точнее, в классе NXProxy). Только там переопределяется метод forward - эквивалент описанного только что приема в Smalltalk.
20 Еще один вид заместителя дает паттерн итератор.
21 Практически для любого класса Object является суперклассом самого верхнего уровня. Поэтому выражение «нет суперкласса» означает то же самое, что «Object не является суперклассом».
22 Упрощая задачу, мы игнорируем приоритеты операторов и предполагаем, что их учет возложен на объект, строящий дерево разбора.
23 Грейди Буч (Grady Booch) называет внешние и внутренние итераторы соответственно активными и пассивными [Boo94]. Термины «активный» и «пассивный» относятся к роли клиента, а не к действиям, выполняемым итератором.
24 Курсоры - это простой пример применения паттерна хранитель; их реализации имеют много общих черт.
25 Этот интерфейс можно и еще уменьшить, если объединить операции Next, IsDone и CurrentItem в одну, которая будет переходить к следующему объекту и возвращать его. Если обход завершен, то эта операция вернет специальное значение (например, 0). обозначающее конец итерации.
26 Это можно проверять на этапе компиляции, если объявить операторы new и delete закрытыми. Ре-ализовывать их при этом не надо.
27 Операция Traverse в этих примерах - это не что иное, как шаблонный метод с примитивными операциями TestItem и ProcessItem.
28 Отметим, что в нашем примере объект состояния удаляется по завершении итерации. Но оператор delete не будет вызван, если ProcessItem возбудит исключение, поэтому в памяти остается мусор. Это проблема в языке C++, но не в Dylan, где есть сборщик мусора. Решение проблемы обсуждается на стр. 235.
29 Пример основан на описании протокола установления TCP-соединений, приведенном в книге Линча и Роуза [LR93].
30 Таким образом, каждый подкласс TCPState - это одиночка.
31 Можно было бы использовать перегрузку функций, чтобы дать этим операциям одно и то же простое имя, например Visit, так как они уже различаются типом передаваемого параметра. Имеются аргументы как за, так и против подобной перегрузки. С одной стороны, подчеркивается, что все операции выполняют однотипный анализ, хотя и с разными аргументами. С другой стороны, при этом читателю программы может быть не вполне понятно, что происходит при вызове. В общем все зависит от того, часто ли вы применяете перегрузку функций.
32 Если есть двойная диспетчеризация, то почему бы не быть тройной, четверной или диспетчеризации произвольной кратности? Двойная диспетчеризация - это просто частный случай множественной диспетчеризации, при которой выбираемая операция зависит от любого числа типов. (CLOS как раз и поддерживает множественную диспетчеризацию.) В языках с поддержкой двойной или множественной диспетчеризации необходимость в паттерне посетитель возникает гораздо реже.
33 Эта тема красной нитью проходит и через другие паттерны. Абстрактная фабрика, построитель и прототип инкапсулируют знание о том, как создаются объекты. Декоратор инкапсулирует обязанности, которые могут быть добавлены к объекту. Мост отделяет абстракцию от ее реализации, позволяя изменять их независимо друг от друга.
34 См. "The poetry of the language" [AIS+77].
35 В OMT для обозначения диаграмм классов используется термин «диаграмма объектов». Мы же зарезервировали термин «диаграмма объекта» исключительно для описания структуры объекта.
36 В OMT определены также ассоциации между классами, изображаемые простыми линиями, соединяющими прямоугольники классов. Хотя на стадии анализа ассоциации полезны, нам кажется, что их уровень слишком высок для выражения отношений в паттернах проектирования, просто потому, что на стадии проектирования ассоциациям следует сопоставить ссылки на объекты или указатели. Ссылки на объекты по сути своей являются направленными и потому лучше подходят для визуализации интересующих нас отношений. Например, классу Drawing (рисунок) известно о классах Shape (фигура), но сами фигуры ничего не «знают» о рисунке, в который они погружены. Выразить такое отношение только лишь с помощью ассоциаций невозможно.