代理模式

来源:互联网 发布:xquartz for mac 安装 编辑:程序博客网 时间:2024/06/05 09:19

定义

代理模式的作用比较容易理解,因为名字已经说明一些。最表面的意思就是提供一个对象的代理对象,通过代理对象来完成目标对象所要完成的功能,其实内部操作仍然是目标对象的操作,不过是添加了一层掩饰。这里所说的代理对象是指与目标对象实现相同接口的类的实例,因为要提供一致性访问,或者说对外不区分所使用的是代理对象还是目标对象。

通常结构为


由上可知代理模式包含如下部分:

1、抽象主题:声明目标方法,即目标对象和代理对象都需要实现的功能(这里定义为接口是因为使用JDK方式作动态代理时需要提供有接口形式的抽象主题)

2、真实主题:即目标类RealSubject,提供具体的方法实现,也是实际使用的方法

3、代理类:与真实主题同样实现抽象主题,在内部保持一个对真实主题的引用,在实现方法中调用真实主题的方法,自身提供的额外方法可以作为辅助函数

简单示例

抽象主题中定义查询数据功能,输入的用户名作为查询条件,在代理类中维持一个查询缓存,默认相同用户所要查询的信息都是相同的,即重复查询

结构如下


参考代码

public class t{public static void main(String[] args) {Target proxy=new Proxy();proxy.Search("tom");proxy.Search("jack");proxy.Search("tom");}}interface Target{//抽象主题类void Search(String name);//抽象方法,查询功能}class RealSubject implements Target{//真实主题类public void Search(String name){//真实查询功能,数据库的访问时间设为1秒try{Thread.sleep(1000);System.out.println(name+"'s data");}catch(InterruptedException e){e.printStackTrace();}}}/*只是演示效果,并不考虑并发环境,否则缓存更新、单例都需要加以同步控制*/class Proxy implements Target{//代理类private final static Map<String,String> map=new HashMap<String,String>();//查询缓存private static Target realsubject=null;//以单例方式引用private boolean Verify(String name){//验证缓存中是否存在return map.containsKey(name);}private void Update(String name){//缓存中不存在时,从数据库查询结果,并更新到缓存map.put(name,"'s data");}public void Search(String name){//查询入口if(Verify(name)){System.out.println(name+map.get(name));return;}if(realsubject==null){//只是单纯的演示单例,具体单例模式参见单例模式realsubject=new RealSubject();}realsubject.Search(name);Update(name);}}

代理模式虽然作用上理解比较简单,只是维持一个对真实主题的引用,但是根据在实际使用中的形式或者说偏重点不同,具有不同的功能。例如

1、当真实主题对象为一个大对象,即初始化资源比较多,需要较长的反应时间,此时使用的代理对象中只需要维持一个对真实主题的引用,并不需要在初始化代理对象时完成一系列复杂的初始化过程,且因为都实现了共同的抽象主题,所以可以提供一致性访问,因此可以大幅度提升系统启动速度。这种方式也就是通常所说的延迟加载,提供虚拟代理对象来替代真实对象,在实际需要使用目标方法时再进行真实对象的初始化工作,例如数据库的连接。

2、对执行目标方法时的权限验证或日志记录,当存在类似的与业务逻辑存在纵向关联关系的行为时,需要提供额外的方法来处理目标方法执行时的环境,当然这更确切的可以说是一个AOP所做的工作,以业务逻辑作为横向执行,则日志记录属于纵向执行,类似于在横向执行中插入一个点,也可以叫做切入点,在切入点执行纵向方法。

当然其他的代理形式有许多,如网络中常用的远程代理,也就是在本地保存一个远程空间对象的代理对象,等等,总之都是利用对原有真实对象的操作,附加以额外方法来是实现的。

总结

代理模式作为常用的设计模式,在代理对象中保存一个对真实对象的引用,或者笼统一点的说法,保存了一个实现了共同抽象主题的具体类的引用。

其形式乍一看挺像之前说过的适配器模式,其实仔细观察其中差别挺大,适配器模式无论是类适配器或者对象适配器,都是对已有功能的转移,来满足目标功能,即利用适配者Adaptee的实现来完成目标类Target的需求,代理模式则是向外界提供一个与真实主题RealSubject同等级别的代理对象,即对外界透明访问,从出发点上可以说两者完全不同。



0 0
原创粉丝点击