代理模式总结

1,什么是代理模式?

GoF对代理模式的描述:

代理模式(Proxy),为其他对象提供一种代理以控制对这个对象的访问[DP].

理解一下这句话:包含了三个角色(其他对象,代理,这个对象),代理存在的意义是方便其他对象控制对这个对象的访问.代理是这个对象的代理,而不是其他对象的代理.现在,我们给这三个角色起个名字,联系一下生活中的场景,其他对象可以是买火车票的人,代理可以是火车票代售点,这个对象可以是火车站;其他对象可以是租房客,代理可以是中介,这个对象可以是房东.我们使用Client表示其他对象,Proxy表示代理,RealSubject表示这个对象.Proxy是如何实现对RealSubject的代理呢?这就需要Proxy和RealSubject实现共同的接口Subject.Proxy类,保存一个RealSubject的引用,这样Proxy就可以访问到RealSubject,并且他们实现了共同的接口Subject,这样代理就可以用来代替RealSubject.

2,代理模式的分类有哪些?

静态代理和动态代理.

静态代理是代理类在程序运行前就已经存在.代理类通常是在java类中定义好的.通常情况下, 静态代理中的代理类和委托类会实现同一接口或是派生自相同的父类.

例子:

Proxy和Client共用的接口

 

public interface Shopping {
    String doShopping(Long money);
}


Client.java类

 

 

public class Client implements Shopping {
    @Override
    public String doShopping(Long money) {
        System.out.println("花了" + money + "元");
        String[] goods = {"衣服", "裤子", "鞋子", "帽子"};
        return Arrays.toString(goods);
    }
}


Proxy.java类

public class Proxy implements Shopping {
    private Shopping mBase;

    public Proxy(Shopping mBase) {
        this.mBase = mBase;
    }

    @Override
    public String doShopping(Long money) {
        String goods = mBase.doShopping(money);
        System.out.println("代理贪污掉: " + "裤子");
        String[] result = {"衣服", "鞋子", "帽子"};

        return Arrays.toString(result);
    }
}

 

TestStatic.java类(测试类):

public class TestStatic {
    public static void main(String[] args){
        // 普通
        System.out.println("普通: ");
        Shopping client = new Client();
        System.out.println(client.doShopping(100L));

        // 静态代理
        System.out.println("静态代理: ");
        Proxy proxy = new Proxy(client);
        System.out.println(proxy.doShopping(100L));
    }
}


运行打印结果:

 

 

普通: 
花了100元
[衣服, 裤子, 鞋子, 帽子]
静态代理: 
花了100元
代理贪污掉: 裤子
[衣服, 鞋子, 帽子]

 

 

动态代理是代理类在程序运行时才存在的代理方式.

例子:

创建实现了InvocationHandler接口的类ShoppingHandler.java

 

/**
 * 调用处理器,拦截对代理类方法的调用
 */
public class ShoppingHandler implements InvocationHandler {

    /**
     * 调用处理器持有RealSubject的引用
     */
    private Shopping mClient;

    public ShoppingHandler(Shopping mClient) {
        this.mClient = mClient;
    }
    /**
     * 当我们调用代理类对象的方法时,这个“调用”会转送到invoke方法中
     *
     * @param o       代理类对象
     * @param method  调用的是代理类中的哪个方法
     * @param objects 调用代理类中的那个方法的参数
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
        if ("doShopping".equals(method.getName())) {
            Long money = (Long) objects[0];
            String things = (String) method.invoke(mClient, money);
            System.out.println("代理贪污掉: " + "裤子");
            String[] result = {"衣服", "鞋子", "帽子"};

            return Arrays.toString(result);
        }
        return null;
    }
}


测试类:

 

 

public class TestDynamic {
    public static void main(String[] args) {
        Shopping client = new Client();
        // 获取目标对象的代理对象
        /**
         * 参1:ClassLoader loader, 要进行代理类的类加载器
         * 参2:Class<?>[] interfaces, 被代理类实现的接口
         * 参3:InvocationHandler h, 调用处理器
         * 返回: 代理类
         */
        Shopping proxy = (Shopping) Proxy.newProxyInstance(client.getClass().getClassLoader(),
                client.getClass().getInterfaces(),
                new ShoppingHandler(client));
        // 通过代理调用方法
        System.out.println(proxy.doShopping(100L));
    }
}


测试结果:

 

 

花了100元
代理贪污掉: 裤子
[衣服, 鞋子, 帽子]

 

 

 

3,动态代理vs静态代理

 

参考资料:

1,http://blog.csdn.net/hejingyuan6/article/details/36203505

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

willwaywang6

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值