Design Patterns (GoF)

Материал из Home Wiki
Перейти к навигации Перейти к поиску
Версия для печати больше не поддерживается и может содержать ошибки обработки. Обновите закладки браузера и используйте вместо этого функцию печати браузера по умолчанию.

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

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

Abstract Factory

(абстрактная фабрика) (93)

Предоставляет интерфейс для создания семейств, связанных между собой, или независимых объектов, конкретные классы которых неизвестны.

Adapter

(адаптер) (141)

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

Bridge

(мост) (152)

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

Builder

(строитель) (103)

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

Chain of Responsibility

(цепочка обязанностей) (217)

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

Command

(команда) (226)

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

Composite

(компоновщик) (162)

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

Decorator

(декоратор) (173)

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

Facade

(фасад) (183)

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

Factory Method

(фабричный метод) (111)

Определяет интерфейс для создания объектов, при этом выбранный класс инстанцируется подклассами.

Flyweight

(приспособленец) (191)

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

Interpreter

(интерпретатор) (236)

Для заданного языка определяет представление его грамматики, а также интерпретатор предложений языка, использующий это представление.

Iterator

(итератор) (173)

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

Mediator

(посредник) (263)

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

Memento

(хранитель) (272)

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

Observer

(наблюдатель) (281)

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

Prototype

(прототип) (121)

Описывает виды создаваемых объектов с помощью прототипа и создает новые объекты путем его копирования.

Proxy

(заместитель) (203)

Подменяет другой объект для контроля доступа к нему.

Singleton

(одиночка) (130)

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

State

(состояние)(291)

Позволяет объекту варьировать свое поведение при изменении внутреннего состояния. При этом создается впечатление, что поменялся класс объекта.

Strategy

(стратегия) (300)

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

Template Method

(шаблонный метод) (309)

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

Visitor

(посетитель) (314)

Представляет операцию, которую надо выполнить над элементами объекта. Позволяет определить новую операцию, не меняя классы элементов, к которым он применяется.

Некоторые выдержки из текста

Таблица Design pattern space (Пространство паттернов проектирования)

Purpose (Цель)
Scope

(Уровень)

Creational

(Порождающие паттерны)

Structural

(Структурные паттерны)

Behavioral

(Паттерны поведения)

Class Factory Method Adapter Interpreter

Template Method

Object Abstract Factory

Builder

Prototype

Singleton

Adapter

Bridge

Composite

Decorator

Facade

Flyweight

Proxy

Chain of Responsibility

Command

Iterator

Mediator

Memento

Observer

State

Strategy

Visitor

Типичные причины перепроектирования

(38)

Вот некоторые типичные причины перепроектирования, а также паттерны, которые позволяют этого избежать:

  • при создании объекта явно указывается класс. Задание имени класса привязывает вас к конкретной реализации, а не к конкретному интерфейсу. Это может осложнить изменение объекта в будущем. Чтобы уйти от такой проблемы, создавайте объекты косвенно.
    Паттерны проектирования: абстрактная фабрика, фабричный метод, прототип;
  • зависимость от конкретных операций. Задавая конкретную операцию, вы ограничиваете себя единственным способом выполнения запроса. Если же не включать запросы в код, то будет проще изменить способ удовлетворения запроса как на этапе компиляции, так и на этапе выполнения.
    Паттерны проектирования: цепочка обязанностей, команда;
  • зависимость от аппаратной и программной платформ. Внешние интерфейсы операционной системы и интерфейсы прикладных программ (API) различны на разных программных и аппаратных платформах. Если программа зависит от конкретной платформы, ее будет труднее перенести на другие. Даже на «родной» платформе такую программу трудно поддерживать. Поэтому при проектировании систем так важно ограничивать платформенные зависимости.
    Паттерны проектирования: абстрактная фабрика, мост;
  • зависимость от представления или реализации объекта. Если клиент «знает», как объект представлен, хранится или реализован, то при изменении объекта может оказаться необходимым изменить и клиента. Сокрытие этой информации от клиентов поможет уберечься от каскада изменений.
    Паттерны проектирования: абстрактная фабрика, мост, хранитель, заместитель;
  • зависимость от алгоритмов. Во время разработки и последующего использования алгоритмы часто расширяются, оптимизируются и заменяются. Зависящие от алгоритмов объекты придется переписывать при каждом изменении алгоритма. Поэтому алгоритмы, вероятность изменения которых высока, следует изолировать.
    Паттерны проектирования: мост, итератор, стратегия, шаблонный метод, посетитель;
  • сильная связанность. Сильно связанные между собой классы трудно использовать порознь, так как они зависят друг от друга. Сильная связанность приводит к появлению монолитных систем, в которых нельзя ни изменить, ни удалить класс без знания деталей и модификации других классов. Такую систему трудно изучать, переносить на другие платформы и сопровождать. Слабая связанность повышает вероятность того, что класс можно будет повторно использовать сам по себе. При этом изучение, перенос, модификация и сопровождение системы намного упрощаются. Для поддержки слабо связанных систем в паттернах проектирования применяются такие методы, как абстрактные связи и разбиение на слои.
    Паттерны проектирования: абстрактная фабрика, мост, цепочка обязанностей, команда, фасад, посредник, наблюдатель; расширение функциональности за счет порождения подклассов.
  • расширение функциональности за счет порождения подклассов. Специализация объекта путем создания подкласса часто оказывается непростым делом. С каждым новым подклассом связаны фиксированные издержки реализации (инициализация, очистка и т.д.). Для определения подкласса необходимо также ясно представлять себе устройство родительского класса. Например, для замещения одной операции может потребоваться заместить и другие. Замещение операции может оказаться необходимым для того, чтобы можно было вызвать унаследованную операцию. Кроме того, порождение подклассов ведет к комбинаторному росту числа классов, поскольку даже для реализации простого расширения может понадобиться много новых под классов. Композиция объектов и делегирование - гибкие альтернативы наследованию для комбинирования поведений. Приложению можно добавить новую функциональность, меняя способ композиции объектов, а не определяя новые подклассы уже имеющихся классов. С другой стороны, при интенсивном использовании композиции объектов проект может оказаться трудным для понимания. С помощью многих паттернов проектирования удается построить такое решение, где специализация достигается за счет определения одного подкласса и комбинирования его экземпляров с уже существующими.
    Паттерны проектирования: мост, цепочка обязанностей, компоновщик, декоратор, наблюдатель, стратегия;
  • неудобства при изменении классов. Иногда нужно модифицировать класс, но делать это неудобно. Допустим, вам нужен исходный код, а его нет (так обстоит дело с коммерческими библиотеками классов). Или любое изменение тянет за собой модификации множества существующих подклассов. Благодаря паттернам проектирования можно модифицировать классы и при таких условиях.
    Паттерны проектирования: адаптер, декоратор, посетитель.

Вопросы

p152 - что имеется в виду под поддержкой рекурсивной композиции декоратором?