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

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

В общем случае паттерн состоит из четырех основных элементов:

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

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

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

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

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

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

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

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

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


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

Абстрактная операция - операция, которая объявляет сигнатуру, но не реализует ее. В C++ абстрактные операции соответствуют исключительно виртуальным, функциям-членам.

Абстрактная связанность — говорят, что класс А абстрактно связан с абстрактным классом В, если в А есть ссылка на В. Такое отношение мы называем абстрактной связанностью, поскольку А ссылается на тип объекта, а не на конкретный объект.

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

Агрегированный объект - объект, составленный из подобъектов. Подобъекты называются частями агрегата, и агрегат отвечает за них.

Делегирование - механизм реализации, при котором объект перенаправляет или делегирует запрос другому объекту (уполномоченному). Уполномоченный выполняет запрос от имени исходного объекта.

Деструктор — в C++ это операция, которая автоматически вызывается для очистки объекта непосредственно перед его удалением.

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

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

Диаграмма объекта - диаграмма, на которой изображена структура конкретного объекта во время выполнения.

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

Дружественный класс - в C++: класс, обладающий теми же правами доступа к операциям и данным некоторого класса, что и сам этот класс.

Закрытое наследование — в C++: класс, наследуемый только ради реализации.

Замещение - переопределение операции, унаследованной от родительского класса, в подклассе.

Инкапсуляция - результат сокрытия представления и реализации в объекте.

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

Инструментальная библиотека (toolkit) - набор классов, обеспечивающих полезную функциональность, но не определяющих дизайн приложения.

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

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

Класс - определяет интерфейс и реализацию объекта. Описывает

Внутреннее представление и операции, которые объект может выполнять.

Композиция объектов - объединение нескольких объектов для получения более сложного поведения.

Конкретный класс - класс, в котором нет абстрактных операций. Может

иметь экземпляры.

Конструктор - в C++: операция, автоматически вызывающаяся для инициализации новых экземпляров.

Метакласс - в Smalltalk классы являются объектами. Метакласс - это класс объекта-класса.

Наследование - отношение, которое определяет однусущность в терминах другой. В случае наследования класса новый класс определяется в терминах одного или нескольких родительских классов. Новый класс наследует интерфейс и реализацию от своих родителей. Новый класс называется подклассом или производным классом (в C++).

Наследование класса объединяет наследование интерфейса

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

Объект - имеющаяся во время выполнения сущность, в которой хранятся

данные и процедуры для работы с ними.

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

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

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

Отношение осведомленности - говорят, что одному классу известно о другом, если первый ссылается на второй.

Параметризованный тип - тип, где некоторые составляющие типы оставлены неопределенными. Они передаются как параметры в точке использования. В C++ параметризованные типы называются шаблонами.

Паттерн проектирования - паттерн проектирования именует, мотивирует

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

Переменная экземпляра - элемент данных, определяющий часть представления объекта. В C++ используется термин данные-член.

Подкласс - класс, наследующий другому классу. В C++ подкласс называется производным классом.

Подмешанный класс - класс, спроектированный так, чтобы сочетаться с другими классами путем наследования. Подмешанные классы обычно абстрактны.

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

Подтип - один тип называется подтипом другого, если интерфейс первого содержит интерфейс второго.

Полиморфизм - способность подставлять во время выполнения вместо одного объекта другой с совместимым интерфейсом.

Получатель - объект, которому направлен запрос.

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

Протокол - расширяет концепцию интерфейса за счет включения допустимой последовательности запросов.

Родительский класс - класс, которому наследует другой класс. Синонимы - суперкласс (Smalltalk), базовый класс (C++) и класс-предок.

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

Сигнатура - под сигнатурой операции понимается сочетание ее имени, параметров и возвращаемого значения.

Ссылка на объект - значение, которое идентифицирует другой объект.

Супертип — тип родителя, которому наследует данный тип.

Тип - имя конкретного интерфейса.

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

Приложение В. Объяснение


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: