Ответ
Паттерн Декоратор (Decorator) — это структурный паттерн проектирования, который позволяет динамически добавлять новую функциональность объектам, оборачивая их в объекты-декораторы. Он предоставляет гибкую альтернативу наследованию для расширения поведения.
Ключевой принцип: Композиция предпочтительнее наследования. Декоратор реализует тот же интерфейс, что и оборачиваемый компонент, и делегирует ему основную работу, добавляя что-то своё до или после вызова.
Участники:
- Компонент (Component): Общий интерфейс для декорируемых объектов и декораторов.
- Конкретный компонент (Concrete Component): Базовая реализация, которую мы будем декорировать.
- Декоратор (Decorator): Абстрактный класс, реализующий интерфейс Component и содержащий ссылку на него.
- Конкретный декоратор (Concrete Decorator): Добавляет конкретную функциональность.
Классический пример: Система оповещений.
// 1. Компонент - общий интерфейс
interface Notifier {
String send(String message);
}
// 2. Конкретный компонент - базовая реализация
class SimpleNotifier implements Notifier {
@Override
public String send(String message) {
return "Sending basic notification: " + message;
}
}
// 3. Базовый декоратор (может быть абстрактным)
abstract class NotifierDecorator implements Notifier {
protected Notifier wrappedNotifier; // Ссылка на оборачиваемый компонент
public NotifierDecorator(Notifier notifier) {
this.wrappedNotifier = notifier;
}
@Override
public String send(String message) {
return wrappedNotifier.send(message); // Делегирование
}
}
// 4. Конкретные декораторы
class SMSDecorator extends NotifierDecorator {
public SMSDecorator(Notifier notifier) {
super(notifier);
}
@Override
public String send(String message) {
// 1. Вызываем поведение обёрнутого объекта
String baseResult = super.send(message);
// 2. Добавляем своё поведение
return baseResult + "n -> Also sending SMS: " + message;
}
}
class FacebookDecorator extends NotifierDecorator {
public FacebookDecorator(Notifier notifier) {
super(notifier);
}
@Override
public String send(String message) {
return super.send(message) + "n -> Also posting to Facebook: " + message;
}
}
// 5. Клиентский код
public class Client {
public static void main(String[] args) {
Notifier notifier = new SimpleNotifier(); // База
notifier = new SMSDecorator(notifier); // Добавили SMS
notifier = new FacebookDecorator(notifier); // Добавили Facebook
System.out.println(notifier.send("Server is down!"));
}
}
/* Вывод:
Sending basic notification: Server is down!
-> Also sending SMS: Server is down!
-> Also posting to Facebook: Server is down!
*/
Преимущества:
- Гибкость: Поведение объекта можно собирать динамически во время выполнения.
- Соблюдение OCP (Open/Closed Principle): Можно добавлять новую функциональность, не изменяя существующий код.
- Избегание взрывного роста классов: Вместо создания классов
SMSNotifier,FacebookNotifier,SMSAndFacebookNotifierи т.д. используется композиция.
Пример в Java Standard Library: Классы java.io.BufferedInputStream, java.io.DataInputStream являются декораторами для InputStream.