序言
以下为本人写的其他设计模式,感兴趣的同学可以查阅。
白话设计模式之菜鸟提升篇
此头条号中已经发布了其他设计模式,感兴趣的同学可以关注我后进行查阅,同时获取后序更多模式及其他信息。
代理模式(Proxy Pattern)
为某个对象提供对象代理,让代理控制原有对象的访问。代理对象在客户端和原对象之间充当中介的作用,避免和控制了客户端直接访问原对象。例如我们日常生活中购买的部分商品是从代理商那里购买的,我们并不需要直接向厂家或者生产商进行购买,这就是代理模式在生活中的体现。比如以前(非互联网时代)村里,小镇上有部分商店都在代理三大运营商(移动、联通、电信)的缴费(电话费)业务,我们只需要将钱给到代理并告知需要充值多少电话费,他就能为我们完成充值,我们无需直接和运营商接触,这也是典型的代理模式。代理模式在我们的生活和工作中都是普遍存在的。如JDK动态代理,服务器代理等等。根据目的和实现方式的不同代理模式可以细分为:远程代理、虚拟代理、保护代理、缓冲代理、智能引用代理。
-
远程代理(Remote Proxy) :为一个位于不同的地址空间的对象提供一个本地的代理对象,这个不同的地址空间可以是在同一台主机中,也可是在另一台主机中。
-
虚拟代理(Virtual Proxy):如果需要创建一个资源消耗较大的对象,先创建一个消耗相对较小的对象来表示,真实对象只在需要时才会被真正创建。
-
保护代理(Protect Proxy):控制对一个对象的访问,可以给不同的用户提供不同级别的使用权限。
-
缓冲代理(Cache Proxy):为某一个目标操作的结果提供临时的存储空间,以便多个客户端可以共享这些结果。
-
智能引用代理(Smart Reference Proxy):当一个对象被引用时,提供一些额外的操作,例如访问日志记录等。
其实你只需要掌握一种代理模式后,按照字面意思的理解和上述文字说明就能够掌握其他种类的代理模式。也可以简单的理解为:原来Client调用RealTarget的request()方法,现在我们使用代理模式后,Client不在直接调用RealTarget类,而是间接的通过Proxy的request方法来调用RealTarget的request方法,这样我们就能够在Proxy类中对Client的调用做控制等一系列原来无法实现的功能,具体类图如下所示:

代理模式通用模式

客户端调用
根据上图进行类推,远程代理:就是原本你需要进行远程服务器接口的调用,写一大堆复杂TCP,现在设计成代理模式,你只需要调用本地的某个方法即可等待结果返回即可,复杂的远程调用由代理完成,你不用关心远程调用中网络的问题,缓存的问题等一系列复杂问题,你只需关注自身的业务方法即可。
虚拟代理:假设RealTarget是一个非常复杂的类,加载时它会占据很多的系统资源,使得调用端等待时间过长,我们可以使用虚拟代理Proxy,在Proxy中我们可以对RealTarget进行简化,只加载客户端需要的内容或者说优先加载重要内容,这样可以很快的返回给客户端,在这个过程中我们可以另起一个线程进行RealTarget的初始化加载,这样以后客户端在进行调用我们就能够为其提供一个完整的RealTarget。这样做优化了客户端调用等待时间过长的问题,开启新线程做后序工作降低了系统的资源占用(如1万个请求调用同时过来,RealTarget进行全部加载,那么系统短时间资源必定占用很多,可能会导致系统其它功能不能正常运行,使用虚拟代理可以减缓这种短时间的资源占用问题)。
保护代理:假设RealTarget中的request方法一开始是Client直接调用的,现在我们要对RealTarget的request访问做个保护,不是所有用户都能进行访问的,只有部分用户可以进行访问,那么我们使用保护代理模式进行重构,让Client访问Proxy的request方法,我们在Proxy的request方法中完成用户等级校验,如果等级满足需求那么进行RealTarget的request方法访问。
缓冲代理:例如Client调用RealTarget的request方法过于平凡且每次调用返回的结果集都是一样的,为优化该调用性能,我们使用缓存代理模式处理,Client不在直接调用RealTarget而是调用Proxy,我们在Proxy中将RealTarget返回信息做缓存,在每次调用RealTarget前先判断是否存在缓存,存在则返回缓存内容不进行RealTarget的调用,反之亦反。
智能引用代理:例如Client一直是直接调用RealTarget的request方法获取数据,现在我们需要知道RealTarget方法被谁在什么时间调用,那么我们就可以使用智能引用代理模式,在proxy的request方法访问RealTarget的request方法前后进行日志输出。
总结
优点
-
能够协调调用者和被调用者,在一定程度上降低了它们之间的耦合度
-
客户端调用是针对接口编程的,在增加或者修改代理类时,无需修改源代码,方便代理扩展,符合开放闭合原则
缺点
-
由于调用者和被调用者之间增加了代理,势必会影响到系统的反应效率
-
在一定程度上回增加系统的编码难度
今天就先写到这里,如有问题,欢迎吐槽。在此特别感谢design-pattern-java一书的作者,是他让我开始对设计模式产生了感觉。地球不爆炸,我们不放假,good good study day day up !!如有帮助请多多关注!点赞