我试图使用装饰器模式修改我的对象的行为但是遇到了一些障碍,装饰器模式似乎无法按照我想要的方式更改我的对象的功能。
以下是我想要做的一个简单示例:
我有一个带有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。
有没有办法可以修改我对装饰器模式的使用来实现我想要的结果?或者我可以使用其他一些模式/解决方案来实现我的工作方式吗?
由于
答案 0 :(得分:0)
我认为你不能使用装饰器模式实现这个目标。您正在尝试修改现有实例的行为,这不会是微不足道的(如果可能的话)。
以下内容可行:
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
。如果你愿意,装饰者类可以代替你。
答案 1 :(得分:0)
如果你不能修改MyClass
,也许你可以从它派生并使用子类代替?然后,您可以覆盖getValue
。
答案 2 :(得分:0)
你的错误是显而易见的。当您致电MyDecorator.complexStuff()
时,会直接将此来电委托给MyClass decorated
委托,其中getValue()
方法未被覆盖,因为MyDecorator
中的MyClass
覆盖了MyDecorator
MyClass
}。换句话说,MyClass
HAS-A MyDecorator.complexStuff()
,但不是IS-A 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();
}
}
方法,但不能覆盖{{1}}方法:
{{1}}