Паттерн Декоратор динамически наделяет объект новыми возможностями и является гибкой альтернативой субклассированию (то есть наследованию от супер класса) в области расширения функциональности.
Декоратор агрегирует объект и расширяет его функциональность. Добавляемая функциональность реализуется в небольших объектах. Преимущество состоит в возможности динамически добавлять эту функциональность до или после основной функциональности декорируемого объекта.
abstract public class Beverage { protected String desc = "Неизвестный напиток"; protected String getDesc() { return desc; } protected abstract double cost(); } class Espresso extends Beverage { public Espresso() { desc = "Espresso"; } public double cost() { return 1.99; } } class Cappuccino extends Beverage { public Cappuccino() { desc = "Cappuccino"; } public double cost() { return 1.25; } }
public abstract class CondimentDecorator extends Beverage { public abstract String getDesc(); } class Chocolate extends CondimentDecorator { Beverage beverage; public Chocolate(Beverage beverage) { this.beverage = beverage; desc = ", шоколад"; } public String getDesc() { return beverage.getDesc() +desc; } public double cost() { return beverage.cost() + .45; } } class Milk extends CondimentDecorator { private Beverage beverage; public Milk(Beverage beverage) { this.beverage =beverage; desc = ", молоко"; } public String getDesc() { return beverage.getDesc() +desc; } public double cost() { return .20 + beverage.cost(); } }
public class Main { public static void main(String args[]) { Beverage esp = new Espresso(); esp = new Milk(esp); esp = new Chocolate(esp); System.out.println(esp.getDesc()+" $"+esp.cost()); //Espresso, молоко, шоколад $2.64 Beverage cap = new Cappuccino(); cap = new Milk(new Milk(cap)); System.out.println(cap.getDesc()+" $"+cap.cost()); //Cappuccino, молоко, молоко $1.65 } }