设计模式之代理模式
来源:互联网 发布:淘宝模板什么意思 编辑:程序博客网 时间:2024/06/05 20:14
如有转载,请申明:
转载至 http://blog.csdn.net/qq_35064774/article/details/51971796
1 什么是代理模式
代理模式是对象的结构模式。代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。
2 怎么实现代理模式
首先我们要知道代理模式按使用目的可分为以下几种:
* 远程代理:为一个位于不同的地址空间的对象提供一个局域代表对象。
* 虚拟代理:根据需要创建一个资源消耗较大的对象,使得此对象只在需要时才会被真正创建。
* 保护代理:控制对一个对象的访问,如果需要,可以给不同的用户提供不同级别的使用权限。
智能引用代理:当一个对象被引用时,提供一些额外的操作,比如将此对象调用的次数记录下来等。
代理的实现比较复杂,幸运的是,Java支持代理模式。
Java sdk中提供了代理类Proxy和InvocationHandler接口。
我们尝试着解决下面提出的问题。
* 现有一个Car对象,其中有move和fix方法,我们需要计算两个方法的执行时间。但又不能修改Car的方法。
首先,我们按照要求,写一个Car类,有move和fix两个方法,但为了更方便的实现代理和增强扩展性,我们把这move和fix抽象成两个接口Moveable和Fixable。然后由Car实现这两个接口。
package com.ittianyu.proxy.dynamic;public interface Moveable {void move();}
package com.ittianyu.proxy.dynamic;public interface Fixable {void fix(String thing);}
package com.ittianyu.proxy.dynamic;public class Car implements Moveable, Fixable{@Overridepublic void move() {System.out.println("moving...");try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}}@Overridepublic void fix(String thing) {System.out.println("fixing...");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}
再有了Car类之后,我们就需要定义一个实现了InvocationHandler接口的类。
这个类就是Car的代理类会调用的一个接口实现类。
而代理应该做的是,计算被代理类的方法执行前后所用的时间。
我们先考虑一下如何计算某一段代码执行的时间。
大部分童鞋应该都想到了,时间差。
也就是执行那段代码前后都调用System.currentTimeMillis();取得时间戳,然后求差就得到了结果。
所以我们在代理类里也是需要在前后各取一次启动时间。
package com.ittianyu.proxy.dynamic;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;public class TimeInvocationHandler implements InvocationHandler {private Object object;private long start;private long end;// object为被代理的对象,需要我构建的时候传入public TimeInvocationHandler(Object object) {super();this.object = object;}// proxy是代理类@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {//在执行被代理类的方法前的处理this.doBefore();// 执行被代理类的方法,object是被代理的对象,method是它的方法,args是它的所有参数,returnObject是方法返回值Object returnObject = method.invoke(object, args);//在执行被代理类的方法后的处理this.doAfter();return returnObject;}private void doBefore() {start = System.currentTimeMillis();}private void doAfter() {end = System.currentTimeMillis();System.out.println("运行耗时(ms)" + (end - start));}}
最后我们开始测试,定义一个Test类,在main方法中测试
package com.ittianyu.proxy.dynamic;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Proxy;public class Test {public static void main(String[] args) {Car car = new Car();InvocationHandler handler = new TimeInvocationHandler(car);Object proxy = Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), car.getClass().getInterfaces(), handler);((Moveable)proxy).move();((Fixable)proxy).fix("轮胎");}}
这里的Proxy.newProxyInstance返回的类,就是我们的代理类,这个类实现了两个接口,所以我们可以分别转成两个接口来调用其中的方法。
3 在什么情况下使用代理模式
* 当我们需要对某一对象加以不同的控制,但又不能破坏对象内部结构时,就需要代理模式。比如,我们需要在执行某方法之前和之后检测权限或者进行一些处理。
4 代理模式的优点和缺点
根据代理种类不同,其特点也不同。
优点:
* 远程代理:系统可以将网络的细节隐藏起来,使得客户端不必考虑网络的存在。
* 虚拟代理:代理对象可以在必要的时候才被代理的对象加载。
* 保护代理:它可以在运行时间对用户的有关权限进行检查,然后在核实后决定将调用传递给被代理的对象。
* 智能引用代理:在访问一个对象时可以执行一些内务处理操作,比如计数操作等。
缺点:
* 远程代理:客户不会意识到会启动一个i额耗时的远程调用,因此,客户没有必要的思想准备。
- 设计模式之代理模式
- 设计模式之代理模式
- 设计模式之代理模式
- 设计模式之代理模式
- 设计模式之-代理模式
- 设计模式之 代理模式
- 设计模式之代理模式
- 设计模式之代理模式
- 设计模式之代理模式
- 设计模式之代理模式
- 设计模式之代理模式
- 设计模式之代理模式
- 设计模式之代理模式
- 设计模式之-----代理模式
- 设计模式之代理模式
- 设计模式之-代理模式
- 设计模式之代理模式
- 设计模式之代理模式
- HDOJ 1201 18岁生日
- 浅析C/C++中的switch/case陷阱
- Codeforces Round #363 (Div. 1) C LRU
- hihoCoder_1014
- hdoj 4548 美素数
- 设计模式之代理模式
- Scalaz(49)- scalaz-stream: 深入了解-Sink/Channel
- android沉浸式
- jQuery Mobile 工具栏
- poj Aggressive cows
- HDOJ 4548 美素数
- C学习笔记(十二)函数详解
- 旧识——快速傅里叶变换
- 【Codeforces666B】【World Tour】【最短路】