如果我们可以将其限制为接口(任意数量),您正在寻找动态代理。
所以你的问题:如果你首先调用该接口中的方法而不调用装饰器,然后使用装饰器你想要不同的行为,那么给定这个接口实现:
MyInterface o = new MyInterface() {
public Object myMethod(Object blah) {
return "bar";
}
};
这应该做不同的事情,例如改变返回值(和/或其他东西):
System.out.println(o.myMethod(null));
o = decorator(o);
System.out.println(o.myMethod(null));
输出:
bar
foo
这可以通过java中的动态代理来完成:
public static MyInterface decorator(final MyInterface obj) {
InvocationHandler handler = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getName().equals("myMethod")) {
//do something special
return "foo";
}
return method.invoke(obj, args);
}
};
MyInterface proxy = (MyInterface) Proxy.newProxyInstance(
MyInterface.class.getClassLoader(),
obj.getClass().getInterfaces(), //all or limit it to just one or a few
handler);
return proxy;
}
更新:如果您想涉及更多接口(上面更新了代理实例代码以实现接口而不是硬编码):
现在使这项工作:
public static void main(String[] args) {
A o = new A();
System.out.println(o.myMethod(null));
System.out.println(o.myOtherMethod(1));
Object o2 = decorator(o);
System.out.println(((MyInterface) o2).myMethod(null));
System.out.println(((MyInterface2) o2).myOtherMethod(1));
}
带输出:
bar
2
foo <-- changed
2 <- the same behavior
鉴于:
class A implements MyInterface, MyInterface2 {
@Override
public Object myMethod(Object blah) {
return "bar";
}
@Override
public int myOtherMethod(int a) {
return a+1;
}
}