Реферат: Э. Гамма Р. Хелм Р. Джонсон Дж. Влиссидес




Э. Гамма Р. Хелм Р. Джонсон Дж. Влиссидес


Erich Gamma Richard Helm Ralph Johnson John Vlissides

Design Patterns

Elements of Reusable

Object-Oriented Software


Addison-Wesley

An imprint of Addison Wesley Longman, Inc.

Reading, Masachusetts • Harlow, England • Menlo Park, California

Berkley, California • Don Mills, Ontario • Sydney

Bonn • Amsterdam • Tokyo • Mexico City

Э. Гамма Р. Хелм Р. Джонсон Дж. Влиссидес

БИБЛИОТЕКА ПРОГРАММИСТА



















Санкт-Петербург Москва • Харьков • Минск

2001

3. ^ Гамма, Р. Хелм, Р. Джонсон, Дж. Влиссидес

Приемы объектно-ориентированного проектирования Паттерны проектирования

Серия «Библиотека программиста»

, Перевел с английского А. Слинкин

Руководитель проекта ^ И. Захаров

Научный редактор Н. Шалаев
Литературный редактор А. Петроградская

Технический редактор С. Прока

Иллюстрации А. Бахарев

Художник Н. Биржаков

Верстка Л. Пискунова

ББК 32.973.2-018 УДК 681.3.068

Гамма Э., Хелм Р., Джонсон Р., Влиссидес Дж.

П75 Приемы объектно-ориентированного проектирования. Паттерны проектирования. — СПб: Питер, 2001. — 368 с.: ил. (Серия «Библиотека программиста»)

ISBN 5-272-00355-1

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

Издание предназначено как для профессиональных разработчиков, так и для программистов, осваивающих объектно-ориентированное проектирование.

Original English language Edition Copyright© 1995 by Addison Wesley Longman, Inc. © Перевод на русский язык, А. Слинкин, 2001 ©Серия, оформпение, Издательский дом «Питер», 2001 Оригинал-макет подготовлен издательством «ДМК Пресс».

Права на издание получены по соглашению с Addison-Wesley Longman.

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

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

ISBN 5-272-00355-1

ISBN 0-201-63361-2 (англ.)

ЗАО «Питер Бук». 196105, Санкт-Петербург, Благодатная ул., д. 67. Лицензия ИД № 01940 от 05.06.00.

Налоговая льгота - общероссийский классификатор продукции ОК 005-93, том 2; 953000 - книги и брошюры. Подписано в печать 08.10.00. Формат 70х100'/|6. Усл. п. л. 29,67. Тираж 5000 экз. Заказ№ 1997.

Отпечатано с готовых диапозитивов в ГПП «Печатный двор» Министерства РФ по делам печати, телерадиовещания и средств массовых коммуникаций.

197110, Санкт-Петербург, Чкаловский пр., 15.

Посвящается Кэрин

- Э. Гамма

Сильвии

- Р. Хелм

Фейт

- Р. Джонсон

Дрю Энн и Мэттью Джошуа 24:15Ь

- Дж. Влиссидес

^ Отзывы на книгу «Design Patterns: Elements of Reusable Object-Oriented Software»

Одна из самых хорошо написанных и глубоких книг, которые мне доводилось читать... эта работа доказывает необходимость паттернов самым правильным способом: не рассуж­дениями, а примерами.

Стэн Липпман, ^ The C++ Report

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

Том ДеМарко, ^ IEEE Software

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

Санджив Госсайн Journal of Object-Oriented Programming

Эта книга, столь давно ожидаемая, полностью оправдала все предшествовавшие ей рек­ламные посулы. Она подобна справочнику архитектора, в котором приведены проверен­ные временем, испытанные на практике приемы и методы проектирования. Всего авторы отобрали 23 паттерна. Подарите экземпляр этой книги каждому из своих знакомых про­граммистов, желающему усовершенствоваться в своей профессии.

Ларри О'Брайен, ^ Software Development

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

Стив ^ Билов, Journal of Object-Oriented Programming

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

Том Каргилл, The C++ Report


Предисловие 10

Глава 1. Введение в паттерны проектирования 15

Что такое паттерн проектирования 16

Паттерны проектирования в схеме MVC в языке Smalltalk 18

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

Каталог паттернов проектирования 22

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

Как решать задачи проектирования с помощью паттернов 25

Поиск подходящих объектов 25

Определение степени детализации объекта 27

Специфицирование интерфейсов объекта 27

Специфицирование реализации объектов 29

Механизмы повторного использования 32

Сравнение структур времени выполнения и времени компиляции 37

Проектирование с учетом будущих изменений 38

Как выбирать паттерн проектирования 43

Как пользоваться паттерном проектирования 44

^ Глава 2. Проектирование редактора документов 46

Задачи проектирования 46

Структура документа 48

Рекурсивная композиция 49

Глифы 51

Паттерн компоновщик 53

2.3. Форматирование 53

Инкапсуляция алгоритма форматирования 54

Классы Compositor и Composition 54

Стратегия 56

2.4. Оформление пользовательского интерфейса 56

Прозрачное обрамление 57

Моноглиф 58

Паттерн декоратор 60

2.5. Поддержка нескольких стандартов внешнего облика 60

Абстрагирование создания объекта 61

Фабрики и изготовленные классы 61

Паттерн абстрактная фабрика 64

ООП

2.6. Поддержка нескольких оконных систем 64

Можно ли воспользоваться абстрактной фабрикой? 64

Инкапсуляция зависимостей от реализации 65

Классы Window и Windowlmp 67

Подклассы Windowlmp 68

Конфигурирование класса Window с помощью Windowlmp 70

Паттерн мост 70

2.7. Операции пользователя 71

Инкапсуляция запроса 72

Класс Command и его подклассы 73

Отмена операций 74

История команд 75

Паттерн команда 76

2.8. Проверка правописания и расстановка переносов 76

Доступ к распределенной информации 77

Инкапсуляция доступа и порядка обхода 77

Класс Iterator и его подклассы 78

Паттерн итератор 81

Обход и действия, выполняемые при обходе 81

Класс Visitor и его подклассы 86

Паттерн посетитель. - 87

2.9. Резюме 88

^ Глава 3. Порождающие паттерны 89

Паттерн Abstract Factory. 93

Паттерн Builder 102

Паттерн Factory Method 111

Паттерн Prototype 121

Паттерн Singleton 130

Обсуждение порождающих паттернов 138

^ Глава 4. Структурные паттерны 140

Паттерн Adapter 141

Паттерн Bridge 152

Паттерн Composite 162

Паттерн Decorator 173

Паттерн Facade 183

Паттерн Flyweight 191

Паттерн Proxy 203

Обсуждение структурных паттернов 213

Адаптер и мост 213

Компоновщик, декоратор и заместитель 214

^ Глава 5. Паттерны поведения 216

Паттерн Chain of Responsibility. 217

Паттерн Command 227

Содержание

Паттерн Interpreter 236

Паттерн Iterator. 249

Паттерн Mediator. 263

Паттерн Memento 272

Паттерн Observer. 280

Паттерн State 291

Паттерн Strategy 300

Паттерн Template Method 309

Паттерн Visitor. 314

Обсуждение паттернов поведения 328

Инкапсуляция вариаций 328

Объекты как аргументы 328

Должен ли обмен информацией быть инкапсулированным или распределенным ... 329

Разделение получателей и отправителей 330

Резюме 332

^ Глава 6. Заключение 333

6.1. Чего ожидать от паттернов проектирования 333

Единый словарь проектирования 333

Помощь при документировании и изучении 334

Дополнение существующих методов 334

Цель реорганизации 335

Краткая история 336

Проектировщики паттернов 337

Языки паттернов Александра ' 338

Паттерны в программном обеспечении 339

Приглашение 339

На прощание 340

Приложение А. Глоссарий 341

Приложение В. Объяснение нотации 344

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

Диаграмма объектов 345

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

Приложение С. Базовые классы 348

С. 1. List 348

С.2. Iterator 350

С.З. Listlterator 350

С.4. Point 351

С.5. Rect 351

Библиография 353

Алфавитный указатель : 359

Предисловие

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

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

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

Когда вы усвоите работу с паттернами проектирования настолько, что после удачного их применения воскликнете «Ага!», а не будете смотреть в сомнении на получившийся результат, ваш взгляд на объектно-ориентированное проектирова­ние изменится раз и навсегда. Вы сможете строить более гибкие, модульные, по­вторно используемые и понятные конструкции, а разве не для этого вообще суще­ствует объектно-ориентированное проектирование?

Несколько слов, чтобы предупредить и одновременно подбодрить вас. Не огорчайтесь, если не все будет понятно после первого прочтения книги. Мы и сами не все понимали, когда начинали писать ее! Помните, что эта книга не из тех, ко­торых, однажды прочитав, ставят на полку. Мы надеемся, что вы будете возвра­щаться к ней снова и снова, черпая идеи и ожидая вдохновения.

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


Предисловие

иначе участвовали многие люди. Особую благодарность мы выражаем Брюсу Андерсону (Bruce Anderson), Кенту Беку (Kent Beck) и Андре Вейнанду (Andre Weinand) за поддержку и ценные советы. Также благодарим всех рецензентов чер­новых вариантов рукописи: Роджера Билефельда (Roger Bielefeld), Грейди Буча (Grady Booch), Тома Каргилла (Tom Cargill), Маршалла Клайна (Marshall Cline), Ральфа Хайра (Ralph Нуге), Брайана Кернигана (Brian Kernighan), Томаса Лали-берти (Thomas Laliberty), Марка Лоренца (Mark Lorenz), Артура Риля (Arthur Riel), Дуга Шмидта (Doug Schmidt), Кловиса Тондо (Clovis Tondo), Стива Винос-ки (Steve Vinoski) и Ребекку Вирфс-Брок (Rebecca Wirfs-Brock). Выражаем при­знательность сотрудникам издательства Addison-Wesley за поддержку и терпение: Кейту Хабибу (Kate Habib), Тиффани Мур (Tiffany Moore), Лайзе Раффаэле (Lisa Raffaele), Прадипу Сива (Pradeepa Siva) и Джону Уэйту 0°hn Wait). Особая бла­годарность Карлу Кесслеру (Carl Kessler), Дэнни Саббаху (Danny Sabbah) и Мар­ку Вегману (Mark Wegman) из исследовательского отдела компании IBM за нео­слабевающий интерес к этой работе и поддержку.

И наконец, не в последнюю очередь мы благодарны всем тем людям, которые высказывали замечания по поводу этой книги через Internet, ободряли нас и убеж­дали, что такая работа действительно нужна. Вот далеко не полный перечень на­ших «незнакомых помощников»: Ион Авотинс (J°n Avotins), Стив Берчук (Steve Berczuk), Джулиан Бердич (Julian Berdych), Матиас Болен (Matthias Bohlen), Джон Брант (John Brant), Алан Кларк (Allan Clarke), Пол Чизхолм (Paul Chisholm), Йене Колдьюи (Jens Coldewey), Дейв Коллинз (Dave Collins), Джим Коплиен (Jim Coplien), Дон Двиггинс (Don Dwiggins), Габриэль Элиа (Gabriele Elia), Дуг Фельт (Doug Felt), Брайан Фут (Brian Foote), Денис Фортин (Denis Fortin), Уорд Харольд (Ward Harold), Херман Хуэни (Hermann Hueni), Найим Ислам (Nayeem Islam), Бикрамжит Калра (Bikramjit Kalra), Пол Кифер (Paul Keefer), Томас Кофлер (Thomas Kofler), Дуг Леа (Doug Lea), Дэн Лалиберте (Dan LaLiberte), Джеймс Лонг (James Long), Анна-Луиза Луу (Ann Louise Luu), Панди Мадхаван (Pundi Mad-havan), Брайан Мэрик (Brian Marick), Роберт Мартин (Robert Martin), Дэйв Мак-Комб (Dave McComb), Карл МакКоннелл (Carl McConnell), Кристин Мингинс (Christine Mingins), Ханспетер Мессенбек (Hanspeter Mossenbock), Эрик Ньютон (Eric Newton), Марианна Озкан (Marianne Ozkan), Роксана Пайетт (Roxsan Pay-ette), Ларри Подмолик (Larry Podmolik), Джордж Радин (George Radin), Сита Ра-макришнан (Sita Ramakrishnan), Русс Рамирес (Russ Ramirez), Александр Ран (Alexander Ran), Дирк Риэле (Dirk Riehle), Брайан Розенбург (Bryan Rosenburg), Аамод Сейн (Aamod Sane), Дури Шмидт (Duri Schmidt), Роберт Зайдль (Robert Seidl), Хин Шу (Xin Shu) и Билл Уолкер (Bill Walker).

Мы не считаем, что набор отобранных нами паттернов полон и неизменен, он просто отражает нынешнее состояние наших мыслей о проектировании. Мы приветствуем любые замечания, будь то критика приведенных примеров, ссылки на известные способы использования, которые не упомянуты здесь, или предложе­ния по поводу дополнительных паттернов. Вы можете писать нам на адрес изда­тельства Addison-Wesley или на электронный адрес design-patterns@cs.uiuc.edu.


Предисловие

Исходные тексты всех примеров можно получить, отправив сообщение «send design pattern source» no адресу design-patterns-source@cs.uiuc.edu. А теперь также есть Web-страница http://st-www.cs.uiuc.edu/users/patterns/DPBook/DPBook.html. на которой размещается последняя информация и обновления к книге.

Эрих Гамма Маунтин Вью, штат Калифорния

Ричард Хелм Монреаль, Квебек

Ральф Джонсон Урбана, штат Иллинойс

Джон Влиссидес Готорн, штат Нью-Йорк

Август, 1994

^ Вступительное слово

Любая хорошо структурированная объектно-ориентированная архитектура изобилует паттернами. На самом деле, для меня одним из критериев качества объектно-ориентированной системы является то, насколько внимательно разра­ботчики отнеслись к типичным взаимодействиям между участвующими в ней объектами. Если таким механизмам на этапе проектирования системы уделялось достаточное внимание, то архитектура получается более компактной, простой и понятной, чем в случае, когда наличие паттернов игнорировалось.

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

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

Мне выпала честь работать вместе с некоторыми авторами книги над пробле­мами архитектурного дизайна. Я многому научился у этих людей и полагаю, что то же самое можно будет сказать и о вас, после того как вы прочтете эту книгу.

Грейди Буч,

Главный научный сотрудник Rational Software Corporation

^ ПредисловиеСоветы читателю

Книга состоит из двух частей. В главах 1 и 2 рассказывается, что такое паттер­ны проектирования и как с их помощью можно разрабатывать объектно-ориенти­рованные программы. Практическое применение паттернов проектирования де­монстрируется на примерах. Главы 3,4 и 5 - это каталог паттернов проектирования.

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

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

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

Если ваш опыт объектно-ориентированного проектирования невелик, начни­те изучать самые простые и распространенные паттерны:

а абстрактная фабрика;

а адаптер;

а компоновщик;

а декоратор;

а фабричный метод;

а наблюдатель;

а стратегия;

а шаблонный метод.

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

^ Принятые в книге обозначения

Для облегчения работы с книгой издательством «ДМК Пресс» приняты следу­ющие соглашения:

а коды программ, важные операторы, классы, объекты, методы и свой­ства обозначены в книге специальным шрифтом (Courier), что позволяет легко найти их в тексте;

а смысловые акценты, определения, термины, встретившиеся впервые, обозна­чены курсивом;

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

Глава 1. Введение в паттерны проектирования

Проектирование объектно-ориентированных программ - нелегкое дело, а если их нужно использовать повторно, то все становится еще сложнее. Необходимо подо­брать подходящие объекты, отнести их к различным классам, соблюдая разумную степень детализации, определить интерфейсы классов и иерархию наследования и установить существенные отношения между классами. Дизайн должен, с одной стороны, соответствовать решаемой задаче, с другой - быть общим, что­бы удалось учесть все требования, которые могут возникнуть в будущем. Хотелось бы также избежать вовсе или, по крайней мере, свести к минимуму необходимость перепроектирования. Поднаторевшие в объектно-ориентированном проектиро­вании разработчики скажут вам, что обеспечить «правильный», то есть в доста­точной мере гибкий и пригодный для повторного использования дизайн, с первого раза очень трудно, если вообще возможно. Прежде чем считать цель достигнутой, они обычно пытаются опробовать найденное решение на нескольких задачах, и каж­дый раз модифицируют его.

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

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

Поясним нашу мысль через аналогию. Писатели редко выдумывают совершен­но новые сюжеты. Вместо этого они берут за основу уже отработанные в мировой литературе схемы, жанры и образы. Например, трагический герой - Макбет,

^ Введение в паттерны проектирования

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

Все мы знаем о ценности опыта. Сколько раз при проектировании вы испыты­вали дежавю, чувствуя, что уже когда-то решали такую же задачу, только никак не сообразить, когда и где? Если бы удалось вспомнить детали старой задачи и ее решения, то не пришлось бы придумывать все заново. Увы, у нас нет привычки записывать свой опыт на благо другим людям да и себе тоже.

Цель этой книги состоит как раз в том, чтобы документировать опыт разра­ботки объектно-ориентированных программ в виде паттернов проектирования. Каждому паттерну мы присвоим имя, объясним его назначение и роль в проекти­ровании объектно-ориентированных систем. Некоторые из наиболее распростра­ненных паттернов формализованы и сведены в единый каталог.

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

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

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

^ 1.1. Что такое паттерн проектирования

По словам Кристофера Александра, «любой паттерн описывает задачу, которая снова и снова возникает в нашей работе, а также принцип ее решения, причем та­ким образом, что это решение можно потом использовать миллион раз, ничего не изобретая заново» [AIS+77]. Хотя Александр имел в виду паттерны, возникающие при проектировании зданий и городов, но его слова верны и в отношении паттер­нов объектно-ориентированного проектирования. Наши решения выражаются

^ Чтотакое паттерн проектирования

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

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

Задача. Описание того, когда следует применять паттерн. Необходимо сфор­
мулировать задачу и ее контекст. Может описываться конкретная проблема
проектирования, например способ представления алгоритмов в виде объек­
тов. Иногда отмечается, какие структуры классов или объектов свидетель­
ствуют о негибком дизайне. Также может включаться перечень условий, при
выполнении которых имеет смысл применять данный паттерн.

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

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

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

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

Введение в паттерны проектирования

его использовать с учетом других проектных ограничений, каковы будут послед­ствия применения метода. Поскольку любой проект в конечном итоге предстоит реализовывать, в состав паттерна включается пример кода на языке C++ (иногда на Smalltalk), иллюстрирующего реализацию.

Хотя, строго говоря, паттерны используются в проектировании, они основа­ны на практических решениях, реализованных на основных языках объектно-ори­ентированного программирования типа Smalltalk и C++, а не на процедурных (Pascal, С, Ada и т.п.) или объектно-ориентированных языках с динамической ти­пизацией (CLOS, Dylan, Self). Мы выбрали Smalltalk и C++ из прагматических соображений, поскольку чаще всего работаем с ними и поскольку они завоевыва­ют все большую популярность.

^ Выбор языка программирования безусловно важен. В наших паттернах под­разумевается использование возможностей Smalltalk и C++, и от этого зависит, что реализовать легко, а что - трудно. Если бы мы ориентировались на проце­дурные языки, то включили бы паттерны наследование, инкапсуляция и по­лиморфизм. Некоторые из наших паттернов напрямую поддерживаются менее распространенными языками. Так, в языке CLOS есть мультиметоды, которые де­лают ненужным паттерн посетитель. Собственно, даже между Smalltalk и C++ есть много различий, из-за чего некоторые паттерны проще выражаются на одном языке, чем на другом (см., например, паттерн итератор).

^ 1.2. Паттерны проектирования в схеме MVC в языке Smalltalk

В Smalltalk-80 для построения интерфейсов пользователя применяется трой­ка классов модель/вид/контроллер (Model/View/Controller - MVC) [KP88]. Знакомство с паттернами проектирования, встречающимися в схеме MVC, помо­жет вам разобраться в том, что мы понимаем под словом «паттерн».

MVC состоит из объектов трех видов. Модель - это объект приложения, а вид - экранное представление. Контроллер описывает, как интерфейс реагиру­ет на управляющие воздействия пользователя. До появления схемы MVC эти объекты в пользовательских интерфейсах смешивались. MVC отделяет их друг от друга, за счет чего повышается гибкость и улучшаются возможности повтор­ного использования.

М VC отделяет вид от модели, устанавливая между ними протокол взаимодей­ствия «подписка/оповещение». Вид должен гарантировать, что внешнее представ­ление отражает состояние модели. При каждом изменении внутренних данных модель оповещает все зависящие от нее виды, в результате чего вид обновляет себя. Такой подход позволяет присоединить к одной модели несколько видов, обеспечив тем самым различные представления. Можно создать новый вид, не переписывая модель.

На рисунке ниже показана одна модель и три вида. (Для простоты мы опусти­ли контроллеры.) Модель содержит некоторые данные, которые могут быть пред­ставлены в виде электронной таблицы, гистограммы и круговой диаграммы.

^ Паттерны проектирования в схеме MVC

Виды



Модель

Модель оповещает свои виды при каждом изменении значений данных, а виды обращаются к модели для получения новых значений.

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

Еще одно свойство MVC заключается в том, что виды могут быть вложенными. Например, панель управления, состоящую из кнопок, допустимо представить как составной вид, содержащий вложенные, - по одной кнопке на каждый. Пользователь­ский интерфейс инспектора объектов может состоять из вложенных видов, исполь­зуемых также и в отладчике. MVC поддерживает вложенные виды с помощью класса CompositeView, являющегося подклассом View. Объекты класса CompositeView ведут себя так же, как объекты класса View, поэтому могут использоваться всюду, где и виды. Но еще они могут содержать вложенные виды и управлять ими.

Здесь можно было бы считать, что этот дизайн позволяет обращаться с состав­ным видом, как с любым из его компонентов. Но тот же дизайн применим и в ситу­ации, когда мы хотим иметь возможность группировать объекты и рассматривать группу как отдельный объект. Такой подход описывается паттерном компоновщик. Он позволяет создавать иерархию классов, в которой некоторые подклассы опре­деляют примитивные объекты (например, Button - кнопка), а другие - составные объекты (CompositeView), группирующие примитивы в более сложные структуры.

MVC позволяет также изменять реакцию вида на действия пользователя. При этом визуальное представление остается прежним. Например, можно изменить реакцию на нажатие клавиши или использовать всплывающие меню вместо ко­мандных клавиш. MVC инкапсулирует механизм определения реакции в объекте Controller. Существует иерархия классов контроллеров, и это позволяет без труда создать новый контроллер как.вариант уже существующего.

^ Введение в паттерны проектирования

Вид пользуется экземпляром класса, производного от Controller, для реа­лизации конкретной стратегии реагирования. Чтобы реализовать иную страте­гию, нужно просто подставить другой контроллер. Можно даже заменить кон­троллер вида во время выполнения программы, изменив тем самым реакцию на действия пользователя. Например, вид можно деактивировать, так что он вообще не будет ни на что реагировать, если передать ему контроллер, игнорирующий события ввода.

Отношение вид-контроллер - это пример паттерна проектирования страте­гия. Стратегия - это объект для представления алгоритма. Он полезен, когда вы хотите статически или динамически подменить один алгоритм другим, если су­ществует много вариантов одного алгоритма или когда с алгоритмом связаны сложные структуры данных, которые хотелось бы инкапсулировать.

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

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

Как мы будем описывать паттерны проектирования? Графических обозначе­ний недостаточно. Они просто символизируют конечный продукт процесса про­ектирования в виде отношений между классами и объектами. Чтобы повторно воспользоваться дизайном, нам не
еще рефераты
Еще работы по разное