锘??xml version="1.0" encoding="utf-8" standalone="yes"?>
void f() { System.out.println("A: doing f()"); }
void g() { System.out.println("A: doing g()"); }
}
class C {
// delegation
A a = new A();
void f() { a.f(); }
void g() { a.g(); }
// normal attributes
X x = new X();
void y() { /* do stuff */ }
}
public class Main {
public static void main(String[] args) {
C c = new C();
c.f();
c.g();
}
}
Proxy Pattern's 3 roles錛?/p>
1. (abstract common)Subject錛歝ommon interface
2. ProxySubject錛氬惈鏈塼he reference to the RealSubject //delegation
3. RealSubject錛氬疄鐜伴昏緫鐨勭被
綾誨浘濡備笅錛?/p>
鍥?
Java 鍔ㄦ佷唬鐞?/p>
浠嶫DK1.3寮濮嬶紝Java灝卞紩鍏ヤ簡鍔ㄦ佷唬鐞嗙殑姒傚康銆傚姩鎬佷唬鐞嗭紙Dynamic Proxy錛夊彲浠ュ府鍔╀綘鍑忓皯浠g爜琛屾暟錛岀湡姝f彁楂樹唬鐮佺殑鍙鐢ㄥ害銆?/p>
綾誨浘濡備笅錛?/p>
鍥?
鍔ㄦ佷唬鐞嗗拰鏅氱殑浠g悊妯″紡鐨勫尯鍒紝灝辨槸鍔ㄦ佷唬鐞嗕腑鐨勪唬鐞嗙被鏄敱java.lang.reflect.Proxy綾誨湪榪愯鏈熸椂鏍規嵁鎺ュ彛瀹氫箟錛岄噰鐢↗ava鍙嶅皠鍔熻兘鍔ㄦ佺敓鎴愮殑(鍥?鐨勫尶鍚嶅疄鐜扮被)銆傚拰java.lang.reflect.InvocationHandler緇撳悎錛屽彲浠ュ姞寮虹幇鏈夌被鐨勬柟娉曞疄鐜般傚鍥?錛屽浘涓殑鑷畾涔塇andler瀹炵幇InvocationHandler鎺ュ彛錛岃嚜瀹氫箟Handler瀹炰緥鍖栨椂錛屽皢瀹炵幇綾諱紶鍏ヨ嚜瀹氫箟Handler瀵硅薄銆傝嚜瀹氫箟Handler闇瑕佸疄鐜癷nvoke鏂規硶錛岃鏂規硶鍙互浣跨敤Java鍙嶅皠璋冪敤瀹炵幇綾葷殑瀹炵幇鐨勬柟娉曪紝鍚屾椂褰撶劧鍙互瀹炵幇鍏朵粬鍔熻兘錛屼緥濡傚湪璋冪敤瀹炵幇綾繪柟娉曞墠鍚庡姞鍏og銆傝孭roxy綾繪牴鎹瓾andler鍜岄渶瑕佷唬鐞嗙殑鎺ュ彛鍔ㄦ佺敓鎴愪竴涓帴鍙e疄鐜扮被鐨勫璞°傚綋鐢ㄦ埛璋冪敤榪欎釜鍔ㄦ佺敓鎴愮殑瀹炵幇綾繪椂錛屽疄闄呬笂鏄皟鐢ㄤ簡鑷畾涔塇andler鐨刬nvoke鏂規硶銆?/p>
涓嬮潰鏄嬌鐢ㄥ姩鎬佷唬鐞嗙殑姝ラ錛?/p>
1. Client鍚慞roxy璇鋒眰涓涓叿鏈夋煇涓姛鑳界殑瀹炰緥錛?/p>
2. Proxy鏍規嵁Subject錛屼互鑷畾涔塇andler鍒涘緩涓涓尶鍚嶅唴閮ㄧ被錛屽茍榪斿洖緇機lient錛?/p>
3. Client鑾峰彇璇ュ尶鍚嶅唴閮ㄧ被鐨勫紩鐢紝璋冪敤鍦⊿ubject鎺ュ彛縐嶅畾涔夌殑鏂規硶錛?/p>
4. 鍖垮悕鍐呴儴綾誨皢瀵規柟娉曠殑璋冪敤杞崲涓哄鑷畾涔塇andler涓璱nvoke鏂規硶鐨勮皟鐢?/p>
5. invoke鏂規硶鏍規嵁涓浜涜鍒欏仛澶勭悊錛屽璁板綍log錛岀劧鍚庤皟鐢⊿ubjectImpl涓殑鏂規硶
Here is a simple example that prints out a message before and after a method invocation on an object that implements an arbitrary list of interfaces:
public interface Foo { Object bar(Object obj) throws BazException; } public class FooImpl implements Foo { Object bar(Object obj) throws BazException { // ... } } public class DebugProxy implements java.lang.reflect.InvocationHandler { private Object obj; public static Object newInstance(Object obj) { return java.lang.reflect.Proxy.newProxyInstance( obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), new DebugProxy(obj)); } private DebugProxy(Object obj) { this.obj = obj; } public Object invoke(Object proxy, Method m, Object[] args) throws Throwable { Object result; try { System.out.println("before method " + m.getName()); result = m.invoke(obj, args); } catch (InvocationTargetException e) { throw e.getTargetException(); } catch (Exception e) { throw new RuntimeException("unexpected invocation exception: " + e.getMessage()); } finally { System.out.println("after method " + m.getName()); } return result; } }To construct a
DebugProxy
for an implementation of theFoo
interface and call one of its methods:Foo foo = (Foo) DebugProxy.newInstance(new FooImpl()); foo.bar(null);