Декоратор
Decorator
Представление структуры шаблона Декоратор
Представление структуры шаблона Декоратор
Тип структурный
Назначение для динамического подключения к объекту дополнительных обязательств
Плюсы
  • нет необходимости создавать подклассы для расширения функциональности объекта;
  • возможность динамически подключать новую функциональность до или после основной функциональности объекта ConcreteComponent.
Родственные шаблоны Фасад, Адаптер
Описан в Design Patterns Да

Декоратор (англ. Decorator) — структурный шаблон проектирования, предназначенный для динамического подключения дополнительного поведения к объекту. Шаблон Декоратор предоставляет гибкую альтернативу практике создания подклассов с целью расширения функциональности.

Основные характеристики

править

Задача

править

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

Способ решения

править

Декоратор предусматривает расширение функциональности объекта без определения подклассов.

Участники

править

Класс ConcreteComponent — класс, в который с помощью шаблона Декоратор добавляется новая функциональность. В некоторых случаях базовая функциональность предоставляется классами, производными от класса ConcreteComponent. В подобных случаях класс ConcreteComponent является уже не конкретным, а абстрактным. Абстрактный класс Component определяет интерфейс для использования всех этих классов.

Следствия

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

Реализация

править

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

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

Замечания и комментарии

править
  • Хотя объект-декоратор может добавлять свою функциональность до или после функциональности основного объекта, цепочка создаваемых объектов всегда должна заканчиваться объектом класса ConcreteComponent.
  • Базовые классы языка Java широко используют шаблон Декоратор для организации обработки операций ввода-вывода.
  • И декоратор, и адаптер являются обёртками вокруг объекта — хранят в себе ссылку на оборачиваемый объект и часто передают в него вызовы методов. Отличие декоратора от адаптера в том, что адаптер имеет внешний интерфейс, отличный от интерфейса оборачиваемого объекта, и используется именно для стыковки разных интерфейсов. Декоратор же имеет точно такой же интерфейс, и используется для добавления функциональности.
  • Для расширения функциональности класса возможно использовать как декораторы, так и стратегии. Декораторы оборачивают объект снаружи, стратегии же вставляются в него внутрь по неким интерфейсам.
    • Недостаток стратегии: класс должен быть спроектирован с возможностью вставления стратегий, декоратор же не требует такой поддержки.
    • Недостаток декоратора: он оборачивает ровно тот же интерфейс, что предназначен для внешнего мира, что вызывает смешение публичного интерфейса и интерфейса кастомизации, которое не всегда желательно.

Применение шаблона

править

Драйверы-фильтры в ядре Windows (архитектура WDM (Windows Driver Model)) представляют собой декораторы. Несмотря на то, что WDM реализована на не-объектном языке Си, в ней чётко прослеживаются паттерны проектирования — декоратор, цепочка обязанностей, и команда (объект IRP).

Архитектура COM (Component Object Model) не поддерживает наследование реализаций, вместо него предлагается использовать декораторы (в данной архитектуре это называется «агрегация»). При этом архитектура решает (с помощью механизма pUnkOuter) проблему object identity, возникающую при использовании декораторов — identity агрегата есть identity его самого внешнего декоратора.

Примеры

править

Kotlin

править

Ruby

править

Java

править

C#

править

C++

править

D

править

Python

править

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

PHP

править

PHP 5

править

CoffeeScript

править

JavaScript

править

VB.NET

править

Delphi

править

Языки Delphi и Free Pascal поддерживают class helpers, которые делают ненужным использование шаблона декоратор.

Swift

править

Литература

править
  • Алан Шаллоуей, Джеймс Р. Тротт. Шаблоны проектирования. Новый подход к объектно-ориентированному анализу и проектированию = Design Patterns Explained: A New Perspective on Object-Oriented Design. — М.: «Вильямс», 2002. — С. 288. — ISBN 0-201-71594-5.
  • Эрик Фримен, Элизабет Фримен. Паттерны проектирования = Head First Desing Patterns. — СПб.: Питер. — 656 с. — ISBN 978-5-459-00435-9.

Примечания

править
  1. Decorator Pattern. wiki.python.org. Дата обращения: 24 октября 2021. Архивировано 24 октября 2021 года.

Ссылки

править

📚 Artikel Terkait di Wikipedia

Итератор (шаблон проектирования)

$client->printOperation2(); } } Test::go(); } Исходный текст на языке Python from abc import ABCMeta, abstractmethod class Iterator(metaclass=ABCMeta):

Мост (шаблон проектирования)

Overrides Sub Operation() Console.WriteLine("ConcreteImplementorB Operation") End Sub End Class End Namespace Исходный текст на языке Python # Implementor

Шопов, Христо

Deceit & Destiny Aboard the Orient Express 2001 — Shark Hunter 2002 — Python 2 (TV) 2002 — Dark Descent 2002 — Interceptor Force 2 (TV) 2003 — Следвай

Фасад (шаблон проектирования)

$computer = new Computer(); $computer->startComputer(); Исходный текст на языке Python # Сложные части системы class CPU(object): def __init__(self): # ... pass

Интерпретатор (шаблон проектирования)

Interpret(Context context) { context.Result.Push(Value); } } } Исходный текст на языке Python __doc__ = ''' Система для вычисления и манипулирования булевыми выражениями

Стратегия (шаблон проектирования)

public Context { public: void useStrategy() { operation->use(); } void setStrategy(Strategy* o) { operation = o; } }; int main(int /*argc*/, char* /*argv*/[])

LDAP

объектно-ориентированный модуль Perl для работы с LDAP python-ldap и ldaptor — модули для работы с LDAP для Python Java LDAP — Java-библиотека для работы с LDAP

Команда (шаблон проектирования)

inv.Show(); cout << "$$$DOCUMENT$$$" << endl; } } Исходный текст на языке Python from abc import ABCMeta, abstractmethod class Troop: """ Receiver - объект