インターフェイス (任意の数) に制限できる場合は、動的プロキシを探しています。
したがって、あなたの問題:最初にデコレータを呼び出さずにそのインターフェイスでメソッドを呼び出し、次にデコレータを使用して異なる動作が必要な場合、このインターフェイスの実装を考えると:
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;
}
}