我试图使用装饰器模式修改我的对象的行为,但遇到了一个小问题,装饰器模式似乎无法以我想要的方式改变我的对象的功能。
下面是我要做的一个简单的例子:
我有一个类,它有一个用于int的getter和其他一些使用getter进行计算的“复杂”类。
public class MyClass implements MyInterface {
private int value = 5;
@Override
public int getValue() {
return value;
}
@Override
public int complexStuff() {
return 50 + getValue();
}
}我有一个抽象装饰器,它只是将接口定义的所有调用传递给MyClass实例
public abstract class MyDecorator implements MyInterface {
private MyClass decorated;
public MyDecorator(MyClass decorated) {
this.decorated = decorated;
}
@Override
public int getValue() {
return decorated.getValue();
}
@Override
public int complexStuff() {
return decorated.complexStuff();
}
}我希望能够修饰一个MyClass实例来修改getValue()方法的行为,从而使complexStuff()也受到影响。
例如,如果我像这样装饰一个MyClass实例:
MyDecorator myDecorator = new MyDecorator(myClassInstance) {
@Override
public int getValue() {
return 100;
}
};按照我目前的实现方式,对myDecorator.getValue()的调用将返回100,但对myDecorator.complexStuff()的调用将返回55,就好像MyClass实例尚未修饰一样。我想要的是调用myDecorator.complexStuff()返回150。
有没有办法可以修改我对装饰器模式的使用,以达到我想要的结果?或者其他一些我可以使用的模式/解决方案,让它以我想要的方式工作?
谢谢
发布于 2013-08-20 17:02:54
我不认为您可以使用装饰器模式来实现此目标。您正在尝试修改现有实例的行为,这不会是微不足道的(如果可能的话)。
下面这样的代码将会起作用:
public class MyClass implements MyInterface {
private ValueProvider provider = new ValueProvider() {
@Override
public int getValue() {
return 5;
}
};
// (You may wish to include this method in MyInterface)
public void setValueProvider(ValueProvider provider) {
this.provider = provider;
}
@Override
public int getValue() {
return provider.getValue();
}
@Override
public int complexStuff() {
return 50 + getValue();
}
}然后,您可以在运行时替换不同的ValueProvider。如果你愿意,一个装饰器类可以替你做这个替换。
发布于 2013-08-20 17:21:23
如果你不能修改MyClass,也许你可以从它派生并使用子类来代替?然后,您可以覆盖getValue。
发布于 2018-06-09 17:17:09
你的错误是显而易见的。当您调用MyDecorator.complexStuff()是委托时,此调用直接调用到MyClass decorated委托,其中getValue()方法不会被覆盖,因为它在非MyClass的MyDecorator中被覆盖。换句话说,MyDecorator 有-A MyClass,但不是-A MyClass。
要解决您的问题,只需修改MyDecorator.complexStuff()方法。使用此方法,您可以自由重写getValue()方法,但不能重写complexStuff()方法:
abstract class MyDecorator implements MyInterface {
private final MyClass decorated;
public MyDecorator(MyClass decorated) {
this.decorated = decorated;
}
// this method is overridden, and returns 100 always
@Override
public int getValue() {
return decorated.getValue();
}
@Override
public final int complexStuff() {
return decorated.complexStuff() - decorated.getValue() + getValue();
}
}https://stackoverflow.com/questions/18330406
复制相似问题