设计模式:代理模式
来源:互联网 发布:mac卸载itools 编辑:程序博客网 时间:2024/06/06 00:54
代理模式指将目标对象(被代理对象)的一种或者几种功能交给代理对象管理,代理对象对原功能进行增强,并对外提供调用的。
代理模式可以分为静态代理和动态代理,在具体实现上,又存在多种不同的实现方式。
静态代理:在编译阶段生成代理类
动态代理:在运行时动态生成代理类
静态代理
静态代理根据实现方式的不同,可分为继承方式实现和聚合方式实现。
继承方式实现
UML类图
聚合方式实现
UML类图
示例
假设有一辆车,我们需要记录行驶的时间,再记录行驶日志。
行驶接口
public interface Moveable { void move();}
具有行驶能力的一辆车
public class Car implements Moveable { @Override public void move(){ System.out.println("汽车行驶中..."); Thread.sleep(1000); }}
继承方式
记录行驶时间代理类
public class CarTimeProxy extends Car { @Override public void move() { long startTime = System.currentMillionTime(); super.move(); long endTime = System.currentMillionTime(); System.out.println("本次行驶时间为:"+(endTime-startTime)); }}
记录行驶日志代理类
public class CarTimeLogProxy extends CarTimeProxy { @Override public void move() { System.out.println("开始行驶..."); super.move(); System.out.println("结束行驶..."); }}
客户端
public class Cient { public void static void main(String[] args) { Moveable proxy=new CarTimeLogProxy(); proxy.move(); }}
输出结果
开始行驶...汽车行驶中...本次行驶时间为:1000结束行驶...
聚合方式
记录行驶时间代理类
public class CarTimeProxy implements Moveable { private Moveable targetObject; public CarTimeProxy(Moveable targetObject){ this.targetObject=targetObject; } @Override public void move() { long startTime = System.currentMillionTime(); targetObject.move(); long endTime = System.currentMillionTime(); System.out.println("本次行驶时间为:"+(endTime-startTime)); }}
记录行驶日志代理类
public class CarLogProxy implements Moveable { private Moveable targetObject; public CarLogProxy(Moveable targetObject){ this.targetObject=targetObject; } @Override public void move() { System.out.println("开始行驶..."); targetObject.move(); System.out.println("结束行驶..."); }}
客户端
public class Cient { public void static void main(String[] args) { Moveable car=new Car(); Moveable carTimeProxy = new CarTimeProxy(car); Moveable carLogProxy = new CarLogProxy(carTimeProxy); carLogProxy.move(); }}
需求是多变的
现在需要想记录日志在记录时间!!!于是:
- 继承方式需要 新建立两个代理类CarLogProxy(继承Car)、CarLogTimeProxy(继承CarLogProxy),然后客户端通过CarLogTimeProxy的实例运行move方法。
- 聚合方式不需要新增或者修改代理类,只需要在客户端使用的时候调整一下调用顺序,如下:
Moveable car=new Car();Moveable carLogProxy = new CarLogProxy(car);Moveable carTimeProxy = new CarTimeProxy(carLogProxy );carTimeProxy .move();
由此可以看出,聚合方式更具有灵活性,更能适应多变的需求。
动态代理
借助JDK内置的Proxy实现
代码示例:
public interface IObject { void doSomething();}public class TargetObject implements IObject { @Override public void doSomething() { System.out.println("I can do something..."); }}public class JdkDynamicProxy implements InvocationHandler { // 被代理类 private TargetObject targetObject; // 代理操作 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Method start..."); Object result = method.invoke(targetObject, args); System.out.println("Method stop..."); return result; } // 获取代理对象 public Object getProxyObject(TargetObject targetObject) { this.targetObject = targetObject; Object proxyObject = Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this); return proxyObject; }}public class Client { public static void main(String[] args) { JdkDynamicProxy jdkDynamicProxy = new JdkDynamicProxy(); IObject object = (IObject) jdkDynamicProxy.getProxyObject(new TargetObject()); object.doSomething(); }}
特点:
- 需要实现InvocationHandler
接口实现代理操作,通过Proxy.newInstance
获取代理实例
- 目标类(被代理类)和生成的代理类实现同一接口
借助cglib实现
public class TargetObject { public void doSomething() { System.out.println("I can do something..."); }}public class CglibDynamicProxy implements MethodInterceptor { private TargetObject targetObject; // 代理的具体操作 @Override public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { System.out.println("Method start..."); Object result = methodProxy.invoke(this.targetObject, args); System.out.println("Method stop..."); return result; } // 获取代理对象 public Object getProxyObject(TargetObject targetObject) { this.targetObject = targetObject; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(targetObject.getClass()); enhancer.setCallback(this); return enhancer.create(); }}public class Client { public static void main(String[] args) { CglibDynamicProxy jdkDynamicProxy = new CglibDynamicProxy(); TargetObject targetObject = (TargetObject) jdkDynamicProxy.getProxyObject(new TargetObject()); targetObject.doSomething(); }}
特点:
- 需要实现
MethodInterceptor
接口实现代理操作 - 代理类是被代理类的子类,所以被代理类不能死final的
- 被代理类不需要继承某个接口
参考文献:http://www.cnblogs.com/best/p/5679656.html
阅读全文
1 0
- 设计模式--【代理模式】
- 设计模式:代理模式
- 设计模式--代理模式
- 设计模式---代理模式
- 设计模式-代理模式
- 设计模式---代理模式
- 设计模式 代理模式
- 设计模式-【代理模式】
- 设计模式-代理模式
- 设计模式----代理模式
- 设计模式-代理模式
- 设计模式---代理模式
- 设计模式--代理模式
- 设计模式-代理模式
- 设计模式- 代理模式
- 设计模式---代理模式
- 设计模式 - 代理模式
- 【设计模式】代理模式
- ORA-01810:格式代码出现两次 oracle语句
- CentOS 7下安装python3和创建虚拟环境
- java基础知识总结
- loadImageNotifyRoutine中拿全路径
- 插入排序-二分插入排序
- 设计模式:代理模式
- 《20171109》
- robot framework 初学--打开浏览器
- opencv 手写选择题阅卷 (一)表格设计与识别
- Maven 运行错误GC overhead limit exceeded解决方法
- HDU 6223 Infinite Fraction Path
- codeforces 120E Put Knight!
- 【WEB】HTML标签自带属性title样式修改
- 2017/11/9模拟赛总结