查看维基百科(http://en.wikipedia.org/wiki/Decorator_pattern)上的Decorator模式页面,布局如下所示:
装饰器可以直接实现组件接口(并跳过装饰器界面)吗?
答案 0 :(得分:0)
这是您引用的维基百科页面中的UML图:
在此图中,Decorator 不是一个接口,而是一个抽象类。组件也是不此图中的接口(因为从其继承的ConcreteComponent和 Decorator 类不具有图中箭头的虚线)。我知道这是一个细节,但UML具体是有原因的。
也就是说,任何ConcreteDecorator都可以直接从Component继承(或者如果你的设计使用接口,则实现它的接口),而不使用 Decorator 抽象类。但是,所有 ConcreteDecorators需要聚合一个组件,因此如果您有多个ConcreteDecorator,抽象类可能对避免重复代码很有用。
答案 1 :(得分:0)
使用Decorator模式获得的主要好处是,对于客户端代码,它是透明的。他们不需要了解装饰器,他们可以像对待基本接口的简单旧具体实现一样对待它:
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);
}
}
}