设计模式---代理模式

代理模式分为静态代理和动态代理,静态代理比较简单,动态代理要用到反射机制

静态代理的例子:

日常生活中,想要联系明星出演节目,往往不是通过直接联系明星,而是联系明星的经纪人,也就是代理

UML图如下

不管是明星(SuperStar)还是经纪人(Broker)都实现Star接口,通过操作接口来和经纪人对接

Star接口代码

package cn.designmodel.proxy.staticProxy;

/**
 * 抽象角色,提供代理角色和真实角色对外公共方法
 */
public interface Star {

    void perform();
}

SuperStar代码

package cn.designmodel.proxy.staticProxy;

public class SuperStar implements Star {

    @Override
    public void perform() {
        System.out.println("明星表演节目");
    }

}

Broker代码

package cn.designmodel.proxy.staticProxy;

public class Broker implements Star {

    private Star superStar;
    
    public Broker(Star s) {
        this.superStar = s;
    }
    
    @Override
    public void perform() {
        superStar.perform();
    }

}

最后是测试程序代码

package cn.designmodel.proxy.staticProxy;

public class TestStaticProxy {

    public static void main(String[] args) {
        Star zjy = new SuperStar();
        Star jjr = new Broker(zjy);
        
        jjr.perform();
    }
}

运行结果

明星表演节目

可以看出,通过经纪人(jjr)表演,实现明星(zjy)的表演,这就是静态代理模式

 

动态代理的例子:

比如有个业务A和业务B,不管执行哪个业务,在执行前和执行完都需要有个记录,很像Spring里的切面一样。

业务接口代码

public interface AbstractSubject
{
    public void request();
}

业务A和业务B代码

public class RealSubjectA implements AbstractSubject
{    
    public void request()
    {
        System.out.println("真实主题类A!");
    }
}


public class RealSubjectB implements AbstractSubject
{    
    public void request()
    {
        System.out.println("真实主题类B!");
    }
}

动态代理类

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

public class DynamicProxy implements InvocationHandler
{
    private Object obj;
    
    public DynamicProxy(){}
    
    public DynamicProxy(Object obj)
    {
           this.obj=obj;
       }
       
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
    {
        preRequest();
        method.invoke(obj, args);
        postRequest();
        return null;
    }

    public void preRequest(){
    System.out.println("调用之前!");
    }

    public void postRequest(){
    System.out.println("调用之后!");
    }

}

最后是测试代码

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

public class Client
{
    public static void main(String args[])
    {
    InvocationHandler handler =null;
    AbstractSubject subject=null;
    
    handler=new DynamicProxy(new RealSubjectA());
    subject=(AbstractSubject)Proxy.newProxyInstance(AbstractSubject.class.getClassLoader(), new Class[]{AbstractSubject.class}, handler);
    subject.request();
    
    System.out.println("------------------------------");
    
    handler=new DynamicProxy(new RealSubjectB());
    subject=(AbstractSubject)Proxy.newProxyInstance(AbstractSubject.class.getClassLoader(), new Class[]{AbstractSubject.class}, handler);
    subject.request();
    } 
}

运行结果

调用之前!
真实主题类A!
调用之后!
------------------------------
调用之前!
真实主题类B!
调用之后!

 

对于动态代理,我还有些困惑,写得不是很详细,正在慢慢学习中。。

posted @ 2018-05-25 09:52  面条啊Andrew  阅读(127)  评论(0编辑  收藏  举报