Декоратор в Java: Как добавить логику без изменения кода?

GuDron

dumpz.ws
Admin
Регистрация
28 Янв 2020
Сообщения
9,534
Реакции
1,550
Credits
33,516
Когда использовать?
- Когда нужно добавить поведение к объекту динамически.
- Когда нельзя или не хочется менять исходный код класса.
- Когда необходимо сохранить принцип открытости/закрытости (OCP из SOLID).

Как это работает?
Декоратор — это обёртка вокруг базового объекта. Он реализует тот же интерфейс, но внутри может добавлять новую логику.

Пример использования
Допустим, у нас есть базовый интерфейс Notifier, который отправляет уведомления:
Java:
public interface Notifier {
    void send(String message);
}
И его простая реализация:
Java:
public class BasicNotifier implements Notifier {
    @Override
    public void send(String message) {
        System.out.println("Отправка сообщения: " + message);
    }
}
Теперь добавим декораторы, которые расширяют функциональность:
Декоратор для отправки в Slack:
Java:
public class SlackNotifierDecorator implements Notifier {
    private final Notifier wrapped;

    public SlackNotifierDecorator(Notifier wrapped) {
        this.wrapped = wrapped;
    }

    @Override
    public void send(String message) {
        wrapped.send(message); // вызываем базовый метод
        System.out.println("Дополнительно отправляем в Slack: " + message);
    }
}

Декоратор для отправки в Email:
Java:
public class EmailNotifierDecorator implements Notifier {
    private final Notifier wrapped;

    public EmailNotifierDecorator(Notifier wrapped) {
        this.wrapped = wrapped;
    }

    @Override
    public void send(String message) {
        wrapped.send(message);
        System.out.println("Дополнительно отправляем Email: " + message);
    }
}

Использование:
Java:
public class Main {
    public static void main(String[] args) {
        Notifier notifier = new BasicNotifier();
        notifier = new SlackNotifierDecorator(notifier);
        notifier = new EmailNotifierDecorator(notifier);

        notifier.send("Привет, мир!");
    }
}

Что произойдет?
Код:
Отправка сообщения: Привет, мир!
Дополнительно отправляем в Slack: Привет, мир!
Дополнительно отправляем Email: Привет, мир!

Итог:
1. Мы не изменяли код BasicNotifier, но добавили новую функциональность.
2. Гибкость: можем легко комбинировать декораторы в любом порядке.
3. Код остаётся чистым и расширяемым.