Паттерн проектирования «Декоратор» / «Decorator»
Паттерн декоратор (Decorator) – один из наиболее известных и распространенных паттернов проектирования, используемых в Java. Он позволяет динамически добавлять новую функциональность к объектам, не изменяя их исходный код. Это очень удобно, когда нужно добавить дополнительные возможности к уже существующему объекту.
Пример использования паттерна декоратор в Java: Предположим, у нас есть интерфейс Pizza
, который имеет методы getDescription()
и getCost()
. Этот интерфейс представляет собой базовый класс для разных типов пиццы.
public interface Pizza {
String getDescription();
double getCost();
}
Теперь мы хотим добавить новые возможности к объекту Pizza
, не меняя его исходный код. Для этого мы создадим класс-декоратор PizzaDecorator
, который также реализует интерфейс Pizza
.
public abstract class PizzaDecorator implements Pizza {
protected Pizza pizza;
public PizzaDecorator(Pizza pizza) {
this.pizza = pizza;
}
}
Класс PizzaDecorator
имеет ссылку на объект pizza
, который он декорирует. Он также реализует методы интерфейса Pizza
.
Теперь мы можем создать конкретные декораторы, которые будут добавлять новые возможности к объекту Pizza
. Например, мы можем создать декоратор CheeseDecorator
, который будет добавлять сыр к пицце.
public class CheeseDecorator extends PizzaDecorator {
public CheeseDecorator(Pizza pizza) {
super(pizza);
}
public String getDescription() {
return pizza.getDescription() + ", Cheese";
}
public double getCost() {
return pizza.getCost() + 2.00;
}
}
Декоратор CheeseDecorator
добавляет сыр к пицце. Он также имеет ссылку на объект pizza
, который он декорирует, и реализует методы интерфейса Pizza
.
Теперь мы можем создать объекты Pizza
и добавлять к ним декораторы. Например, мы можем создать объект PepperoniPizza
и добавить к нему декоратор CheeseDecorator
.
Pizza pepperoniPizza = new PepperoniPizza();
pepperoniPizza = new CheeseDecorator(pepperoniPizza);
System.out.println(pepperoniPizza.getDescription() + ": $" + pepperoniPizza.getCost());
В этом примере мы создали объект PepperoniPizza
, а затем добавили к нему декоратор CheeseDecorator
. Мы также вывели на консоль описание пиццы и ее стоимость.
Вывод на консоль будет следующим: Pepperoni, Cheese: $12.00
Этот пример демонстрирует,
как паттерн декоратор может быть использован для добавления новой функциональности к существующим объектам, не изменяя их исходный код. Таким образом, мы можем создавать более гибкие и модульные приложения, которые легче поддерживать и расширять.
Помимо добавления новых возможностей, паттерн декоратор также может быть использован для убирания возможностей. Например, мы можем создать декоратор NoCheeseDecorator
, который будет убирать сыр с пиццы.
public class NoCheeseDecorator extends PizzaDecorator {
public NoCheeseDecorator(Pizza pizza) {
super(pizza);
}
public String getDescription() {
return pizza.getDescription().replace(", Cheese", "");
}
public double getCost() {
return pizza.getCost() - 2.00;
}
}
Этот декоратор убирает сыр с пиццы. Он также имеет ссылку на объект pizza
, который он декорирует, и реализует методы интерфейса Pizza
.
Теперь мы можем создать объект PepperoniPizza
и добавить к нему декораторы CheeseDecorator
и NoCheeseDecorator
.
Pizza pepperoniPizza = new PepperoniPizza();
pepperoniPizza = new CheeseDecorator(pepperoniPizza);
pepperoniPizza = new NoCheeseDecorator(pepperoniPizza);
System.out.println(pepperoniPizza.getDescription() + ": $" + pepperoniPizza.getCost());
В этом примере мы создали объект PepperoniPizza
, а затем добавили к нему декоратор CheeseDecorator
и NoCheeseDecorator
. Мы также вывели на консоль описание пиццы и ее стоимость.
Вывод на консоль будет следующим: Pepperoni: $10.00
Этот пример демонстрирует, как паттерн декоратор может быть использован для убирания возможностей объекта.
В заключение, паттерн декоратор – это очень мощный инструмент для добавления новых возможностей к объектам и убирания ненужных возможностей. Он позволяет создавать более гибкие и модульные приложения, которые легче поддерживать и расширять. Кроме того, паттерн декоратор является одним из основных паттернов проектирования, используемых в Java, и важен для понимания любого Java-разработчика.