代理模式 代理模式的应用场景:
一个对象不能直接访问另外一个对象的时候,我们可以通过访问该对象的代理对象去访问它。
在不修改类的源码的情况下,动态地增强类的方法,便于程序的扩展
动态地给接口创建代理对象,动态地实现接口中的方法
统一在方法执行之前做前置处理工作,在方法执行之后做后置处理工作,这样可以大大减少代码中的重复代码。这其实就是Spring中的AOP思想
面向对象设计有一个基本原则:开放封闭原则,对扩展开放对修改封闭
改变/增强一个方法,我们又哪些办法可以做到:
继承
装饰者模式:
装饰者和被装饰者要实现相同的接口
将被装饰者的对象传入到装饰者中
如果不需要增强的方法由被装饰者完成,装饰者只增强方法
代理模式:静态代理和动态代理
代理模式的组成部分:
代理者
委托者(被代理者)
接口
代理模式的特点:
代理者和委托者要实现相同的接口
将委托者的对象传入到代理者中
如果不需要增强的方法由委托者完成,代理者只增强方法
代理模式的分类:
静态代理模式:包含委托类、代理类以及统一的接口
动态代理模式:包含委托类和统一的接口,不包含代理类,而是使用反射机制在调用的时候动态生成代理对象
一.静态代理 1.Diagrams
2.代码实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 public interface IKindWomen { void happy () ; } public class Jinlian implements IKindWomen { @Override public void happy () { System.out.println("金莲正在happy..." ); } } public class Wangpo implements IKindWomen { private IKindWomen women; public Wangpo (Jinlian jinlian) { this .women = jinlian; } @Override public void happy () { System.out.println("open room" ); women.happy(); System.out.println("clear room" ); } } @Test public void test () { Jinlian jinlian = new Jinlian(); Wangpo wangpo = new Wangpo(jinlian); wangpo.happy(); }
二.动态代理 1.Diagrams
2.代码实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 public interface IKindWoman { void happy () ; double collect (double money) ; } public class Jinlian implements IKindWoman { @Override public void happy () { System.out.println("金莲正在happy..." ); } @Override public double collect (double money) { System.out.println("金莲收款: " + money); return money; } } @Test public void test () { Jinlian jinlian = new Jinlian(); Class clazz = jinlian.getClass(); ClassLoader classLoader = clazz.getClassLoader(); Class[] interfaces = clazz.getInterfaces(); IKindWoman proxyInstance = (IKindWoman) Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler() { @Override public Object invoke (Object proxy, Method method, Object[] args) throws Throwable { String methodName = method.getName(); if ("happy" .equals(methodName)){ System.out.println("open room" ); method.invoke(jinlian,args); System.out.println("clear room" ); return null ; } if ("collect" .equals(methodName)){ double money = (double ) args[0 ]; System.out.println("扣除中介费 40%: " + money*0.4 ); return method.invoke(jinlian, money*0.6 ); } return method.invoke(jinlian,args); } }); proxyInstance.happy(); double collect = proxyInstance.collect(800 ); System.out.println(collect); }