Что такое паттерн проектирования Decorator
1️⃣ Как кратко ответить
Паттерн проектирования Decorator — это структурный паттерн, который позволяет динамически добавлять новые функциональности объектам, оборачивая их в классы-обертки (декораторы). Это позволяет расширять возможности объектов без изменения их кода и без использования наследования.
2️⃣ Подробное объяснение темы
Паттерн Decorator используется для добавления новых функциональностей объектам динамически, без изменения их структуры. Это достигается путем создания класса-обертки, который содержит объект и добавляет к нему новые методы или изменяет существующие.
Зачем нужен Decorator?
- Гибкость: Позволяет добавлять функциональность объектам на лету, без изменения их кода.
- Композиция вместо наследования: Избегает создания множества подклассов для каждой комбинации функциональностей.
- Принцип открытости/закрытости: Объекты остаются открытыми для расширения, но закрытыми для модификации.
Как работает Decorator?
Decorator работает путем оборачивания объекта в другой объект, который реализует тот же интерфейс. Это позволяет декоратору перехватывать вызовы методов и добавлять к ним дополнительное поведение.
Пример использования
Рассмотрим пример, где у нас есть интерфейс Coffee, и мы хотим добавлять различные добавки к кофе, такие как молоко или сахар.
// Интерфейс, который будет реализован всеми классами кофе
interface Coffee {
String getDescription();
double getCost();
}
// Конкретная реализация кофе
class SimpleCoffee implements Coffee {
public String getDescription() {
return "Simple coffee";
}
public double getCost() {
return 5.0;
}
}
// Абстрактный класс декоратора, который реализует интерфейс Coffee
abstract class CoffeeDecorator implements Coffee {
protected Coffee decoratedCoffee;
public CoffeeDecorator(Coffee decoratedCoffee) {
this.decoratedCoffee = decoratedCoffee;
}
public String getDescription() {
return decoratedCoffee.getDescription();
}
public double getCost() {
return decoratedCoffee.getCost();
}
}
// Конкретный декоратор, добавляющий молоко
class MilkDecorator extends CoffeeDecorator {
public MilkDecorator(Coffee decoratedCoffee) {
super(decoratedCoffee);
}
public String getDescription() {
return decoratedCoffee.getDescription() + ", milk";
}
public double getCost() {
return decoratedCoffee.getCost() + 1.5;
}
}
// Конкретный декоратор, добавляющий сахар
class SugarDecorator extends CoffeeDecorator {
public SugarDecorator(Coffee decoratedCoffee) {
super(decoratedCoffee);
}
public String getDescription() {
return decoratedCoffee.getDescription() + ", sugar";
}
public double getCost() {
return decoratedCoffee.getCost() + 0.5;
}
}
// Пример использования
public class DecoratorPatternExample {
public static void main(String[] args) {
Coffee coffee = new SimpleCoffee();
System.out.println(coffee.getDescription() + " $" + coffee.getCost());
// Добавляем молоко
coffee = new MilkDecorator(coffee);
System.out.println(coffee.getDescription() + " $" + coffee.getCost());
// Добавляем сахар
coffee = new SugarDecorator(coffee);
System.out.println(coffee.getDescription() + " $" + coffee.getCost());
}
}
Объяснение кода
-
Интерфейс
Coffee: Определяет методыgetDescription()иgetCost(), которые должны быть реализованы всеми классами кофе. -
Класс
SimpleCoffee: Реализует интерфейсCoffeeи предоставляет базовую реализацию кофе. -
Абстрактный класс
CoffeeDecorator: Реализует интерфейсCoffeeи содержит ссылку на объектCoffee, который он декорирует. МетодыgetDescription()иgetCost()делегируют вызовы декорируемому объекту. -
Классы
MilkDecoratorиSugarDecorator: Наследуют отCoffeeDecoratorи добавляют свою функциональность, изменяя методыgetDescription()иgetCost(). -
Класс
DecoratorPatternExample: Демонстрирует использование декораторов для добавления молока и сахара к кофе. Каждый декоратор добавляет свою функциональность, изменяя описание и стоимость кофе.
Decorator позволяет легко комбинировать различные функциональности, создавая гибкие и расширяемые системы.
🔒 Подпишись на бусти автора и стань Алигатором, чтобы получить полный доступ к функционалу сайта и отслеживать свой прогресс!
Подписаться