分享

Design Pattern: delegation

 Neil@Sung 2012-03-29

Design Pattern: delegation

 class A {
     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();
     }
}

posted @ 2008-12-14 09:34 Xiaobo Sun 阅读(21) | 评论 (0) | 编辑 收藏

Design Pattern: Proxy, dynamic Proxy

代理模式

 Proxy Pattern's 3 roles:

1.  (abstract common)Subject:common interface

2.  ProxySubject:含有the reference to the RealSubject //delegation

3.  RealSubject:实现逻辑的类

类图如下:

图1

Java 动态代理

从JDK1.3开始,Java就引入了动态代理的概念。动态代理(Dynamic Proxy)可以帮助你减少代码行数,真正提高代码的可复用度。

 类图如下:

图2 

动态代理和普通的代理模式的区别,就是动态代理中的代理类是由java.lang.reflect.Proxy类在运行期时根据接口定义,采用Java反射功能动态生成的(图2的匿名实现类)。和java.lang.reflect.InvocationHandler结合,可以加强现有类的方法实现。如图2,图中的自定义Handler实现InvocationHandler接口,自定义Handler实例化时,将实现类传入自定义Handler对象。自定义Handler需要实现invoke方法,该方法可以使用Java反射调用实现类的实现的方法,同时当然可以实现其他功能,例如在调用实现类方法前后加入Log。而Proxy类根据Handler和需要代理的接口动态生成一个接口实现类的对象。当用户调用这个动态生成的实现类时,实际上是调用了自定义Handler的invoke方法。

下面是使用动态代理的步骤:

1.  Client向Proxy请求一个具有某个功能的实例;

2.  Proxy根据Subject,以自定义Handler创建一个匿名内部类,并返回给Client;

3.  Client获取该匿名内部类的引用,调用在Subject接口种定义的方法;

4.  匿名内部类将对方法的调用转换为对自定义Handler中invoke方法的调用

5. invoke方法根据一些规则做处理,如记录log,然后调用SubjectImpl中的方法

 

Examples

 

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 the Foo interface and call one of its methods:

    Foo foo = (Foo) DebugProxy.newInstance(new FooImpl());foo.bar(null);

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多