代理模式

22 篇文章 0 订阅
17 篇文章 0 订阅

什么是代理模式

代理模式为另一个对象提供一种代理以控制对这个对象的访问。

为什么使用代理模式

当处于某种原因(安全等)考虑,不希望客户直接访问某个对象时,可以提供一个代理对象来访问这个对象。或者希望跟踪某个对象中的方法调用,记录这些执行情况,这时就可以利用代理模式添加一些额外的功能,而又不破坏原有的代码。现实生活中,打官司要找的律师,明星的经纪人等也是代理模式。

另外,java EE框架Spring的AOP(面向切面编程)的原理就是动态代理。

示例

代理模式分为两种: 静态代理和动态代理。
静态代理是自己创建代理类,在编译前就已经存在.class文件,代理类和被代理类的关系在运行前就已确定。

静态代理

静态代理类图:
这里写图片描述

Express是代理类和被代理类的接口,YundaExpress是被代理类,TaobaoProxy是代理类。

Express类:

public interface Express {
    void deliverExpress(String goods);
    void getStateInfo(String goods);
}

YundaExpress类:

public class YundaExpress implements Express{
    public void deliverExpress(String goods) {
        System.out.println("韵达快递将为您寄送:" + goods);
    }

    public void getStateInfo(String goods) {
        System.out.println("您的快递:" + goods + " 已经到目的站,正在为您配送!");
    }
}

TaobaoProxy类:

public class TaobaoProxy implements Express{

    private Express express;

    protected TaobaoProxy(Express express) {
        this.express = express;
    }

    public void deliverExpress(String goods) {
        System.out.println("淘宝卖家已通知快递揽件:" + goods);
        express.deliverExpress(goods);
    }

    public void getStateInfo(String goods) {
        System.out.println("亲,您的快递" + goods + "快到了哟!");
        express.getStateInfo(goods);
    }
}

测试类:

public class TestStaticProxy {

    public static void shop(String goods, Express express) {
        express.deliverExpress(goods);
        express.getStateInfo(goods);
    }

    public static void main(String [] args) {
        String goods = "球衣";
        shop(goods, new YundaExpress());
        shop(goods, new TaobaoProxy(new YundaExpress()));
    }
}

输出:

韵达快递将为您寄送:球衣
您的快递:球衣 已经到目的站,正在为您配送!
淘宝卖家已通知快递揽件:球衣
韵达快递将为您寄送:球衣
亲,您的快递球衣快到了哟!
您的快递:球衣 已经到目的站,正在为您配送!

动态代理

动态代理是运行时创建代理对象并处理所代理方法的调用。动态代理所做的所有的调用都会被重定向到单一的调用处理器上。

动态代理类图:
这里写图片描述

RealObject类是被代理类,DynamicProxy是代理类,DynamicProxyHandler是处理所有调用的处理器。
他们的调用顺序是:
这里写图片描述

Interface类:

public interface Interface {
    void doSomething(String thing);
}

RealObject类:

public class RealObject implements Interface {
    public void doSomething(String thing) {
        System.out.println("RealObject do " + thing);
    }
}

DynamicProxyHandler类:

public class DynamicProxyHandler implements InvocationHandler {
    //被代理对象
    private Object proxied;

    public DynamicProxyHandler(Object proxied) {
        this.proxied = proxied;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        return method.invoke(this.proxied, args);
    }
}

DynamicProxy类:

public class DynamicProxy<T> {
    public static <T> T newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler handler) {
        if (true) {
            (new BeforeSomething()).exec();
        }
        return (T) Proxy.newProxyInstance(loader, interfaces, handler);
    }
}

测试类Client:

public class Client {
    public static void main(String [] args) {
        Interface proxied = new RealObject();
        InvocationHandler handler = new DynamicProxyHandler(proxied);
        Interface proxy = DynamicProxy.newProxyInstance(proxied.getClass().getClassLoader(),proxied.getClass().getInterfaces(),handler);
        proxy.doSomething("sing");
    }
}

输出:

Before do something
RealObject do sing

代码下载:https://github.com/ByrsH/Design-Patterns/tree/master/Design%20Patterns/src/main/java/com/yrs/proxy

参考

  1. 《java编程思想》
  2. 《设计模式之禅》
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值