Паттерн «Декоратор»
Паттерн Декоратор позволяет добавлять новую функциональность к существующему объекту, не изменяя его структуру. Этот тип шаблона проектирования относится к структурным паттернам и служит обёрткой для существующего класса.
Паттерн Декоратор динамически изменяет поведение объекта, оборачивая объект в классы декораторов.
Этот паттерн создаёт класс декоратора, который оборачивает исходный класс и предоставляет дополнительную функциональность, сохраняя целостность сигнатур методов класса.
Мы используем следующий пример, чтобы продемонстрировать использование паттерна Декоратор. Здесь мы будем декорировать фигуру разными цветами, не изменяя класс фигуры.
summary
назначение
Динамически добавлять объекту дополнительные обязанности, не изменяя его структуру. Паттерн Декоратор предлагает гибкую альтернативу наследованию для расширения функциональности.
Основные проблемы, которые необходимо решить
- Избегать добавления статических возможностей через наследование, особенно когда количество подклассов быстро растёт.
- Позволяет динамически добавлять или изменять функциональность объекта во время выполнения.
Сценарий использования
- Когда нужно расширить функциональность класса, не добавляя большое количество подклассов.
- Когда нужно динамически добавлять или удалять функциональность объекта.
Подход к реализации
- Определите интерфейс компонентаСоздайте интерфейс, который задаёт стандарт для объектов, к которым можно динамически добавлять обязанности.
- Создайте конкретные компонентыКонкретные классы, реализующие этот интерфейс и предоставляющие базовую функциональность.
- Создайте абстрактный декораторРеализует тот же интерфейс, хранит ссылку на интерфейс компонента и может в любой момент динамически добавлять функциональность.
- Создайте конкретные декораторыРасширяет абстрактный декоратор, добавляя дополнительные обязанности.
Ключевой код
- Интерфейс ComponentОпределяет стандарт для объектов, которые можно декорировать.
- Класс ConcreteComponentКонкретные классы, реализующие интерфейс Component.
- Абстрактный класс DecoratorРеализует интерфейс Component и содержит ссылку на интерфейс Component.
- Класс ConcreteDecoratorРасширяет класс Decorator, добавляя дополнительную функциональность.
Пример приложения
- 72 превращения Царя обезьян: Сунь Укун (ConcreteComponent) получает новые способности через превращение (Decorator).
- Декоративная картина в рамке: Картина (ConcreteComponent) может улучшить эффект отображения, добавив стекло (ConcreteDecorator) и рамку (ConcreteDecorator).
Преимущества
- Слабая связанностьКлассы декораторов и декорируемые классы могут изменяться независимо, не влияя друг на друга.
- Гибкость: Можно динамически добавлять или удалять функциональность.
- Замена наследованияПредоставляет способ расширить функциональность объекта вне наследования.
Недостатки
- СложностьМногоуровневое декорирование может увеличить сложность системы.
Рекомендации по использованию
- Когда нужно динамически расширить функциональность, рассмотрите использование паттерна Декоратор.
- Сохраняйте согласованность интерфейсов декораторов и конкретных компонентов, чтобы обеспечить гибкость.
Примечания
- Паттерн Декоратор может заменить наследование, но его следует использовать осторожно, чтобы избежать чрезмерного декорирования, ведущего к усложнению системы.
Структура
Паттерн Декоратор включает следующие ключевые роли:
- Абстрактный компонент: определяет общий интерфейс или абстрактный класс для исходных объектов и объектов-декораторов и может служить родительским классом или интерфейсом для классов конкретных компонентов.
- Конкретный компонент: это исходный декорируемый объект, определяющий объект, к которому нужно добавить новую функциональность.
- Абстрактный декоратор: наследуется от абстрактного компонента, содержит объект абстрактного компонента, определяет тот же интерфейс, что и абстрактный компонент, и может хранить другие объекты-декораторы через композицию.
- Конкретный декоратор: реализует интерфейс абстрактного декоратора и отвечает за добавление новой функциональности к абстрактному компоненту. Конкретные декораторы обычно выполняют свои собственные операции до или после вызова методов исходного объекта.
Шаблон Декоратор позволяет многоуровневое расширение функциональности путём вложенного обёртывания нескольких объектов-декораторов. Каждый конкретный класс декоратора может выборочно добавлять новую функциональность, сохраняя согласованность интерфейса объекта.
Реализация
Мы создадимShapeинтерфейс и реализациюShapeкласс сущности интерфейса. Затем мы создаём реализацию, котораяShapeАбстрактный класс декоратора для интерфейса.ShapeDecorator, иShapeобъект в качестве его переменной экземпляра.
RedShapeDecoratorреализуетShapeDecoratorкласс сущности.
DecoratorPatternDemoИспользование классаRedShapeDecoratorдля декорированияShapeобъекта.

Шаг 1
Создайте интерфейс:
Shape.java
Шаг 2
Создайте класс сущности, реализующий интерфейс.
Rectangle.java
Circle.java
Шаг 3
Создайте реализациюShapeАбстрактный класс декоратора для интерфейса.
ShapeDecorator.java
Шаг 4
Создайте расширенныйShapeDecoratorкласс декоратора сущности для класса.
RedShapeDecorator.java
Шаг 5
ИспользованиеRedShapeDecoratorдля декорированияShapeобъекта.
DecoratorPatternDemo.java
Шаг 6
Выполните программу, выведите результат:
Circle with normal border Shape: Circle Circle of red border Shape: Circle Border Color: Red Rectangle of red border Shape: Rectangle Border Color: RedДругие расширения