装饰器可以是组件的直接子代吗?

Can decorators be a direct child of the component?

查看维基百科上的 Decorator 模式页面 (http://en.wikipedia.org/wiki/Decorator_pattern),布局看起来像这样:

装饰器是否可以直接实现组件接口(并跳过装饰器接口)?

这是您引用的维基百科页面中的 UML 图:

在这个图中,装饰器不是一个接口,而是一个抽象class。组件也不是此图中的接口(因为从它继承的 ConcreteComponent 和 Decorator class 没有虚线从图中的箭头)。我知道这是一个细节,但 UML 是特定的是有原因的。

就是说,任何 ConcreteDecorator 都可以直接从 Component 继承(或者如果您的设计使用接口,则实现它的接口)而无需使用 Decorator 抽象 class。但是,all ConcreteDecorators 需要聚合一个组件,因此如果您有多个 ConcreteDecorator,抽象 class 可能有助于避免重复代码。

装饰器模式的主要好处是,对于客户端代码来说,它是透明的。他们不需要了解装饰器,他们可以将其视为基本接口的普通旧具体实现:

ThingDoer thingDoer = new ThingDoerDecorator(new AwesomeThingDoer());
ThingDoer otherThingDoer = new AwesomeThingDoer();

thingDoer.doThing();
otherThingDoer.doThing();

这是唯一可能的,因为装饰器实现了与它正在装饰的东西相同的接口。如果它不实现这个接口,你就失去了这个模式的大部分功能。

但是,有时基础装饰器实现

abstract class BaseThingDoerDecorator implements ThingDoer {
    private ThingDoer thingDoer;

    protected BaseDecorator(ThingDoer thingDoer) {
        this.thingDoer = thingDoer;
    }

    @Override
    public void doThing() {
        thingDoer.doThing();
    }
}

现在做这样的事情变得实用了:

ThingDoer thingDoer = new BaseThingDoerDecorator(new AwesomeThingDoer()) {
    @Override
    public void doThing() {
        System.out.println("This is an anonymous decorator");
        super.doThing();
    }
};

或者您可能希望所有装饰器都免受基础组件中异常的影响:

abstract class BaseThingDoerDecorator implements ThingDoer {
    // Same as above...
    // ...
    @Override
    public void doThing() {
        try {
            thingDoer.doThing();
        } catch (Exception e) {
            log(e);
        }
    }
}