Android 设计模式 之 代理模式
2018-01-07 14:12
435 查看
代理模式介绍
代理模式(Proxy Pattern)也称为委托模式,是结构型设计模式的一种,代理模式在各类开发中运用的相当广泛,不论是j2ee,android还是ios,都能看到它的身影,所以说设计模式无处不在。
代理模式的定义:
为其他对象提供一种代理以控制这个对象的访问。通俗一点:找别人做你想做但是做不了的事情。
代理模式的UML类图,如图:
角色介绍:
(1) 抽象主题(Subject):定义了真实主题(RealSubject)和代理 (Proxy)的公共接口,这样就在任何时候使用真实主题(RealSubject)的地方使用代理(Proxy)。 (2) 代理(Proxy):保存一个引用使得代理可以直接访问真实主题,并提供一个与Subject的接口相同的接口,这样代理就可以代替真实主题。 (3) 真实主题(RealSubject):定义Proxy所代表的真实主题。 (4) 客户类(Client):即使用代理类的类型。
代理模式的简单实现
背景描述
在生活中代理模式也是经常存在,比如2011年老罗针对西门子冰箱门关不严,进行维权。假设找到了律师进行维权,那么这种方式就是代理模式,当然老罗可以自己打官司,也可以自己打官司,有相同的地方,也有不同的地方。相同的地方在于:
1、 诉讼申请:都需要提交原告的资料,如姓名、年龄、事情缘由、想达到的目的。
2、 诉讼取证:都需要经过法院的取证调查,开庭争辩等过程。
3、 诉讼完成:最后拿到审判结果。
不同地方在于:
1、 节省时间:老罗省事了,让专业的人做专业的事,不需要自己再去了解法院那一套繁琐复杂的流程。
2、 成功性概率:把握更大了。
通过上面的例子,我们注意到代理模式有几个重点。
1、 被代理的角色(老罗)
2、 代理角色(律师)
3、 协议(不管是代理和被代理谁去做,都需要做的事情,抽象出来就是协议)
具体代码实现
定义诉讼协议接口ILawProtocol.java:
/** *诉讼协议接口:规定诉讼的一般流程 */ public interface ILawProtocol { void submit();//提交申请 void burden();//进行举证 void defend();//开始辩护 void finish();//诉讼完成 }
定义具体的诉讼人LaoLuo .java:
/* * 具体的诉讼人:继承诉讼接口 */ public class LaoLuo implements ILawProtocol{ @Override public void submit() { // TODO Auto-generated method stub System.out.println("申请:西门子冰箱质量缺陷,特此申请民事仲裁!"); } @Override public void burden() { // TODO Auto-generated method stub System.out.println("证据:这是购买冰箱的发票,以及冰箱质量问题的视频!"); } @Override public void defend() { // TODO Auto-generated method stub System.out.println("辩护:我们证据确凿,必须得到应该的赔偿!"); } @Override public void finish() { // TODO Auto-generated method stub System.out.println("诉讼完成:判决西门子北京分公司在七日之内退还老罗购买冰箱的成本!"); } }
定义代理律师类Lawyer .java
/* * 代理律师类:继承诉讼接口 */ public class Lawyer implements ILawProtocol{ private ILawProtocol mILawSuit;//关联一个诉讼人 public Lawyer(ILawProtocol mILawSuit) { super(); this.mILawSuit = mILawSuit; } @Override public void submit() { // TODO Auto-generated method stub mILawSuit.submit();//提交申请 } @Override public void burden() { // TODO Auto-generated method stub mILawSuit.burden();//进行举证 } @Override public void defend() { // TODO Auto-generated method stub mILawSuit.defend();//开始辩护 } @Override public void finish() { // TODO Auto-generated method stub mILawSuit.finish();//诉讼完成 } }
开庭审理测试Test.java:
import java.lang.reflect.Proxy; public class Test { public static void main(String[] args) { //构造一个具体要诉讼的人:老罗 ILawProtocol laoluo=new LaoLuo(); /**使用静态代理**/ //构造一个代理律师,并将老罗作为构造参数传进去 ILawProtocol lawyer=new Lawyer(laoluo); //执行诉讼人的相关行为 lawyer.submit(); lawyer.burden(); lawyer.defend(); lawyer.finish(); } }
打印结果如下:
诉讼申请:西门子冰箱质量缺陷,特此申请民事仲裁! 诉讼证据:这是购买冰箱的发票,以及冰箱质量问题的视频! 诉讼辩护:我们证据确凿,必须得到应该的赔偿! 诉讼完成:判决西门子北京分公司在七日之内退还老罗购买冰箱的成本!
上文使用的是静态代理,但是静态代理后期扩展和维护比较困难,因为代码写的太死,没有可替换的余地;针对代码写得死能想到什么解决办法?对,就是反射。使用反射可以很到的解决决定加载哪个代理类的问题,避免了每个代理类都要重复写的问题,这就是动态代理。
新建一个动态代理类DynamicProxy .java:
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class DynamicProxy implements InvocationHandler{ //继承InvocationHandler接口 private Object obj;//被代理的类引用 public DynamicProxy(Object obj) {//关联被代理的类 this.obj = obj; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //调用被代理类对象的方法 Object result=method.invoke(obj, args); return result; } }
然后修改客户类如下:
import java.lang.reflect.Proxy; public class Test { public static void main(String[] args) { //构造一个具体要诉讼的人:老罗 ILawProtocol laoluo=new LaoLuo(); /**使用动态代理**/ DynamicProxy dynamicProxy=new DynamicProxy(laoluo);//构造一个动态代理 //获取被代理类老罗的ClassLoader ClassLoader loader=laoluo.getClass().getClassLoader(); //动态的构造一个代理者律师类 ILawProtocol lawyerT=(ILawProtocol)Proxy.newProxyInstance( loader, new Class[]{ILawProtocol.class}, dynamicProxy); //实现ILawProtocol的四个方法: lawyerT.submit(); lawyerT.burden(); lawyerT.defend(); lawyerT.finish(); } }
打印结果同上。
代理模式除了分为静态代理和动态代理两种分法以外,还有其他按使用场景分类:
远程代理(Remote Proxy): 为一个位于不同地址空间的的对象提供一个本地的代理。
虚拟代理(Virtual Proxy):如果需要创建一个消耗较大的对象,先创建一个消耗较小的对象来表示,真实对象只在需要时才被真实创建。
安全代理(Protection Proxy):用来控制对真实对象的访问权限
Android源码中的代理模式分析
Android源码中有不少的代理模式实现,比如源码里的ActivityManagerProxy代理类,其具体代理的是ActivityManagerNative的子类ActivityManagerService,ActivityManagerService 的功能是负责四大组件的启动/切换/调度、进程的管理/调度等; ActivityManagerService 继承自 ActivityManagerNative 类,并实现了 Watchdog.Monitor 和 BatteryStatsImpl.BatteryCallback接口;而 ActivityManagerNative 继承自 Binder 类,并实现了 IActivityManager 接口。
class ActivityManagerProxy implements IActivityManager{ //代码省略... }
ActivityManagerProxy 实现了IActivityManager接口,该接口定义了Activity相关的接口方法,其中有一些我们在应用开发中也时常接触到。
public interface IActivityManager extends IInterface{ public int startActivity(){}; public Intent registerReceiver(){}; public void unregisterReceiver(){}; public ComponentName startService(){}; public int stopService(){}; public int bindService(){}; //省略... }
上面的IActivityManager这个接口类就相当于代理模式中的抽象主题,那么真正的实现主题是什么呢?就是上面我们提到的继承于ActivityManagerNative 的ActivityManagerService类,这几个类之间的关系如下:
通过类图,我们可以清晰的看到ActivityManagerProxy和ActivityManagerNative 都实现了IActivityManager接口,严格的说ActivityManagerProxy就是代理部分,ActivityManagerNative 就是真实部分,但ActivityManagerNative 是一个抽象类,并不过多的处理具体逻辑,大部分具体逻辑由其子类ActivityManagerService承担。
ActivityManagerService是系统级的Service并且运行于独立的进程空间中,可以通过ServiceManager来获取它。而ActivityManagerProxy也是运行在独立的进程空间中,两者并不相同,因此ActivityManagerProxy与ActivityManagerService的通信必定是通过跨进程来进行的,从类图中也可以看到,这里跨进程的实现是基于Android的Binder机制,并且此处的代理模式实质是远程代理模式。
ActivityManagerProxy在实际的逻辑处理中并未过多的被外部类引用,因为在Android中管理和维护Activity相关信息的类是另外一个叫做ActivityManager的类,ActivityManager虽然说是管理者Activity的相关信息,但是实质上其大多数逻辑都是由ActivityManagerProxy承担。
下面的类关系图很好的描述了ActivityManagerProxy与ActivityManager之间的调用关系:
ActivityManagerService里的源码非常的复杂庞大,后续会继续学习并分享给大家。
总结
通过本篇文章需要掌握以下几点: (1)代理模式的定义及使用场景,并会简单使用;
(2)理解动态代理和静态代理的区别;
(3)理解InvocationHandler和Proxy.newProxyInstance的使用;
推荐文章:
1 http://yangguangfu.iteye.com/blog/815787
将代理模式的三种角色与水浒传里相关人物对应起来,很形象生动,Big赞。
转载自:http://blog.csdn.net/happy_horse/article/details/51544995
相关文章推荐
- Android 进阶之路:常见设计模式之代理模式二
- 跟着Android学设计模式:代理(proxy)
- Android设计模式之代理模式Proxy浅显易懂的详细说明
- java/android 设计模式学习笔记(9)---代理模式
- Android 设计模式之代理模式
- Android设计模式------代理模式
- android 设计模式之代理模式
- Android开发中无处不在的设计模式——动态代理模式
- Android中设计模式无处不在之简单工厂模式和代理模式
- Android 内功心法(1.4)——android常用设计模式之代理模式
- Android 设计模式之(一)单例,代理,外观模式
- Android设计模式应用-代理模式
- 跟着Android学设计模式:代理(proxy)
- 设计模式五 监听器模式(android) & 代理模式(ios)
- Android设计模式之动态代理,实现方法拦截功能
- Android设计模式之代理模式(Proxy Pattern)
- java/android 设计模式学习笔记(9)---代理模式
- Android设计模式------代理模式
- Android设计模式-代理模式
- Android开发中无处不在的设计模式——动态代理模式