Android设计模式之代理模式 Proxy( 三 )


Android设计模式之代理模式 Proxy

文章插图
所以我们必须使用由真实对象指定的代理才可以正常得访问.
IHouse house = new House("Downton Abbey", 5000);house = house.getProxy();Log.i(TAG, "looking for a perfect house");house.getHouseInfo();Log.i(TAG, "thinking");house.signContract();house.payFees();
但是这里的强制代理有个Bug,强制代理其实并没有生效,还是可以直接访问House,例如我通过下面的方式来进行访问,只是通过创建并获取代理,但是我不用代理还是直接用House的实例进行访问,这个时候还是可以正常访问的.后续会想办法解了这个Bug并且更新上来的.
IHouse house = new House("Downton Abbey", 5000);house.getProxy();//这里只是通过getProxy创建出代理Log.i(TAG, "looking for a perfect house");house.getHouseInfo();Log.i(TAG, "thinking");house.signContract();house.payFees();
4.动态代理
上面介绍的都是自己先写好的代理类,这样代理关系都是固定的,当代理多个真实对象的时候就要写多个代理类,并且会产生冗余的代码,扩展性和可维护性都不高,而动态代理是基于反射实现了在程序运行的过程中才决定代理什么对象.像AOP的核心思想就是动态代理.(这里使用的是Java的动态代理)
既然是动态代理就不需要也不需要实现接口了,这里写一个实现的接口,并且提供一个根据Proxy构建出来的代理实例给.在通过反射调用真实对象具体的方法之前打印出该方法的名字.
public class ProxyHandler implements InvocationHandler{private final String TAG = ProxyHandler.class.getSimpleName();Object targetObj;public Object newProxyInstance(Object targetObj){this.targetObj = targetObj;return Proxy.newProxyInstance(targetObj.getClass().getClassLoader(),targetObj.getClass().getInterfaces(), this);}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {Object ret;Log.i(TAG, "method name:" + method.getName());ret = method.invoke(targetObj, args);return ret;}}
ProxyHandler proxy = new ProxyHandler();IHouse house = (IHouse) proxy.newProxyInstance(new House("Downton Abbey", 5000));Log.i(TAG, "looking for a perfect house");house.getHouseInfo();Log.i(TAG, "thinking");house.signContract();house.payFees();Log.i(TAG, "so easy");
从结果可以看出在真正真实对象的方法之前都会打印出方法名,也可以在这里做一些其他的对象控制.
Android设计模式之代理模式 Proxy

文章插图
这个时候整个过程的时序图就变成下面的样子了,通过JDK的Proxy对象和反射的机制来支撑起来动态代理的核心功能.
Android设计模式之代理模式 Proxy

文章插图
三.总结
代理模式的使用场景还是挺多的,可以降低对象的复杂度,对项目进行解耦(特别是动态代理的AOP)等,学习设计模式其实最适合的方法就是拿来用,在适用于该模式的场景下灵活得去运用它才算是真正的掌握一种模式.