装饰器可以是组件的直接子代吗?
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);
}
}
}
查看维基百科上的 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);
}
}
}