用Java动态代理实现委托模式

来源:互联网 发布:excel2010编程入门教程 编辑:程序博客网 时间:2024/05/17 03:16
委托模式是软件设计模式中的一项基本技巧。在委托模式中,有两个对象参与处理同一个请求,接受请求的对象将请求委托给另一个对象来处理。
委托模式是一项基本技巧,许多其他的模式,如状态模式、策略模式、访问者模式本质上是在更特殊的场合采用了委托模式。
委托模式使得我们可以用聚合来替代继承,它还使我们可以模拟mixin。?
“委托”在C#中是一个语言级特性,而在Java语言中没有直接的对应,但是我们可以通过动态代理来实现委托!代码如下:

InvocationHandler 用于实现代理。

 

如果不用InvocationHandler接口实现代理的话,我们写代码是这样的:


定义一个接口:

Java code

interface Greet
{
    void sayHello(String name);

    void goodBye();
}

 

实现这个接口:

 

Java code

class GreetImpl implements Greet
{
    public void sayHello(String name)
    {
        System.out.println("Hello " + name);
    }

    public void goodBye()
    {
        System.out.println("Good bye.");
    }
}

 

 

实现一个代理类

 

Java code

public class SimpleProxy implements Greet
{
    private Greet greet = null;

    SimpleProxy(Greet greet)
    {
        this.greet = greet;
    }

    public void sayHello(String name)
    {
        System.out.println("--before method sayHello");
        greet.sayHello(name);
        System.out.println("--after method sayHello");
    }

    public void goodBye()
    {
        System.out.println("--before method goodBye");
        greet.goodBye();
        System.out.println("--after method goodBye");
    }

    /**
     * @param args
     */
    public static void main(String[] args)
    {        Greet tmp = new GreetImpl();        //生成代理
        Greet greet = new SimpleProxy(tmp);
     greet.sayHello("walter");
        greet.goodBye();

    }
}

 

 

===============================================================================

 

代理其实没什么的,再看看如果实现了InvocationHandler接口, 
我们怎样实现代理。 
还是要实现原来的Greet接口。 
接口的实现还是GreetImpl。

 

Java code

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

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)
    {
        //Greet接口的實現:GreetImpl
        this.obj = obj;
    }

     //Method m:調用的方法
   //Object[] args:方法要傳入的參數     //invoke实现对GreetImpl中方法的调用,同时也可以在这里加入自己想要实现的操作,    //虽然调用原GreetImpl中的方法重要,但我想这里更看重的是通过自定义处理实现GreetImpl中没有的功能
    public Object invoke(Object proxy, Method m, Object[] args) throws Throwable
    {
        Object result;
        try
        {
            //自定義的處理
            System.out.println("--before method " + m.getName());
            //調用GreetImpl中方法
            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;
    }

    /**
     * @param args
     */
    public static void main(String[] args)
    {
        Greet tmp = new GreetImpl();
        
        Greet greet = (Greet) DebugProxy.newInstance(tmp);
           //生成的greet和tmp有相同的hashCode
           //通过DebugProxy构造的greet比原temp拥有更多功能
       greet.sayHello("walter");
           greet.goodBye();
    }
}


原创粉丝点击