# 简介

装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装

** 这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。** 一般的,我们为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀。

装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。

# 相关结构

在装饰者模式中,为了让系统具有更好的灵活性和可扩展性,我们通常会定义一个抽象装饰类,而将具体的装饰类作为它的子类。

# Component

抽象构件:它是具体构件和抽象装饰类的共同父类,声明了在具体构件中实现的业务方法,它的引入可以使客户端以一致的方式处理未被装饰的对象以及装饰之后的对象,实现客户端的透明操作。

# ConcreteComponent

具体构件(就是要被装饰的类):它是抽象构件类的子类,用于定义具体的构件对象,实现了在抽象构件中声明的方法,装饰器可以给它增加额外的职责(方法)

# Decorator

抽象装饰类:它也是抽象构件类的子类,用于给具体构件增加职责,但是具体职责在其子类中实现。它维护一个指向抽象构件对象的引用,通过该引用可以调用装饰之前构件对象的方法,并通过其子类扩展该方法,以达到装饰的目的。

# ConcreteDecorator

具体装饰类:它是抽象装饰类的子类,负责向构件添加新的职责。每一个具体装饰类都定义了一些新的行为,它可以调用在抽象装饰类中定义的方法,并可以增加新的方法用以扩充对象的行为。

# 例子

为了能够更方便理解例子,这里先给一下 UML 类图

UML类图

设计不同种类的饮料,饮料可以添加配料,比如可以添加牛奶,并且支持动态添加新配料。每增加一种配料,该饮料的价格就会增加,要求计算一种饮料的价格。

在 DarkRoast 饮料上新增新添加 Mocha 配料,之后又添加了 Whip 配料。DarkRoast 被 Mocha 包裹,Mocha 又被 Whip 包裹。它们都继承自相同父类,都有 cost () 方法,外层类的 cost () 方法调用了内层类的 cost () 方法。

// Component 设计
public interfacce Beverage {
    double cost();
}
// ConcreteComponent
public class DarkRoast implements Beverage {
    @Override
    public double cost() {
        return 1;
    }
}
// Decorator
public abstract class CondimentDecorator implements Beverage {
    protected Beverage beverage;
}

在上面已经提到, Decorator 是一个抽象类,具体的装饰由子类实现

// ConcreteDecorator-A
public class Milk extends CondimentDecorator {
    public Milk(Beverage beverage) {
        this.beverage = beverage;
    }
    @Override
    public double cost() {
        return 1 + beverage.cost();
    }
}
// ConcreteDecorator-B
public class Mocha extends CondimentDecorator {
    public Mocha(Beverage beverage) {
        this.beverage = beverage;
    }
    @Override
    public double cost() {
        return 1 + beverage.cost();
    }
}

运行

public class Client {
    public static void main(String[] args) {
        Beverage beverage = new HouseBlend();
        beverage = new Mocha(beverage);
        beverage = new Milk(beverage);
        System.out.println(beverage.cost());
    }
}

# 参考

菜鸟教程:https://www.runoob.com/design-pattern/decorator-pattern.html

Java 全栈知识体系:https://pdai.tech/md/dev-spec/pattern/12_decorator.html

稀土掘金:https://juejin.cn/post/6844903681322647566