Статьи

Украсить декоратором с рисунком

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

Постановка задачи:

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

Намерение:

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

Решение:

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

Состав

Decorator Design Pattern

Структура шаблона дизайна декоратора

Ниже приведены участники шаблона оформления декоратора:

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

Пример:

Decorator Design Pattern Example

Пример шаблона оформления декоратора

В приведенном выше примере класс Pizza выступает в качестве компонента, а BasicPizza — это конкретный компонент, который необходимо оформить. PizzaDecorator действует как абстрактный класс Decorator, который содержит ссылку на класс Pizza. ChickenTikkaPizza — это ConcreteDecorator, который создает дополнительную функциональность для класса Pizza.

Давайте суммируем шаги для реализации шаблона проектирования декоратора:

  • Создайте интерфейс для BasicPizza (Бетонный компонент), который мы хотим украсить.
  • Создайте абстрактный класс PizzaDecorator, который содержит поле ссылки интерфейса Pizza (оформленный).
  • Примечание. Декоратор (PizzaDecorator) должен расширять интерфейс с одинаковым оформлением (Pizza).
  • Теперь нам нужно передать объект Pizza, который вы хотите украсить, в конструктор декоратора.
  • Давайте создадим Конкретный Декоратор (ChickenTikkaPizza), который должен обеспечить дополнительные функциональные возможности дополнительного топинга.
  • Конкретный Декоратор (ChickenTikkaPizza) должен расширить абстрактный класс PizzaDecorator.
  • Перенаправить методы декоратора (bakePizza ()) в базовую реализацию оформленного класса.
  • Переопределите методы (bakePizza ()), где вам нужно изменить поведение, например, добавление топинга Chicken Tikka.
  • Пусть клиентский класс создаст объект «Тип компонента» (Pizza), создав конкретный декоратор (ChickenTikkaPizza) с помощью Concrete Component (BasicPizza).
  • Чтобы помнить вкратце: новый компонент = бетонный компонент + бетонный декоратор

Пицца пицца = новая ChickenTikkaPizza (новая BasicPizza ());

Пример кода:

BasicPizza.java

1
2
3
public String bakePizza() {
        return 'Basic Pizza';
    }

Pizza.java

1
2
3
public interface Pizza {
    public String bakePizza();
}

PizzaDecorator.java

01
02
03
04
05
06
07
08
09
10
public abstract class PizzaDecorator implements Pizza {
    Pizza pizza;
    public PizzaDecorator(Pizza newPizza) {
        this.pizza = newPizza;
    }
    @Override
    public String bakePizza() {
        return pizza.bakePizza();
    }
}

ChickenTikkaPizza.java

1
2
3
4
5
6
7
8
public class ChickenTikkaPizza extends PizzaDecorator {
    public ChickenTikkaPizza(Pizza newPizza) {
        super(newPizza);
    }
    public String bakePizza() {
        return pizza.bakePizza() + ' with Chicken topping added';
    }
}

Client.java

1
2
3
4
5
public static void main(String[] args) {
        Pizza pizza = new ChickenTikkaPizza(new BasicPizza());
        System.out.println(pizza.bakePizza());
 
    }

Выгоды:

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

недостаток:

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

Интересные моменты:

  • Шаблон адаптера объединяет различные интерфейсы, тогда как шаблон декоратора расширяет функциональные возможности объекта.
  • В отличие от Pattern Decorator Pattern, стратегия меняет исходный объект, не оборачивая его.
  • В то время как шаблон Proxy контролирует доступ к объекту, шаблон декоратора расширяет функциональные возможности объекта.
  • Шаблон Composite и Decorator использует одну и ту же древовидную структуру, но между ними есть тонкие различия. Мы можем использовать составной шаблон, когда нам нужно сохранить группу объектов, имеющих похожее поведение, внутри другого объекта. Однако шаблон декоратора используется, когда нам нужно изменить функциональность объекта во время выполнения.
  • Существуют различные живые примеры шаблона декоратора в Java API.
    • java.io.BufferedReader;
    • java.io.FileReader;
    • java.io.Reader;

Если мы увидим конструктор BufferedReader, то увидим, что BufferedReader оборачивает класс Reader , добавляя дополнительные функции, например readLine (), которого нет в классе reader.

Мы можем использовать тот же формат, что и в примере выше, о том, как клиент использует шаблон декоратора new BufferedReader (new FileReader (new File («File1.txt»))));

Аналогично, BufferedInputStream является декоратором для декорированного объекта FileInputStream .

BufferedInputStream bs = new BufferedInputStream (новый FileInputStream (новый файл («File1.txt»))));

Справка: « Банда четырех» — украсьте с помощью шаблона дизайна декоратора от нашего партнера по JCG Майнака Госвами в блоге Idiotechie .