我学设计模式之代理模式

 

1.  简介

代理模式是对象的结构模式。代理模式给一个对象提供了一个代理对象,并由代理对象控制对象的引用。

              所谓代理,就是一个人或一个机构代表另一个人或机构采取行动。

 

       如果使用代理模式的目的来划分,代理有以下几种:

n         远程代理:为一个对象在不同的地址空间提供局部代表。例如EJB。

n         虚拟代理:更具需要开销很大的对象。例如,当我们打开一个网页的时候,文本会很快显示出来,但图片会慢慢显示出来,浏览器对图片的处理就采用了代理模式。

n         Copy – on – Write代理:

n         保护代理:控制对原始对象的访问。例如:利用代理来访问一些受保护的资源,由代理完成鉴权工作。

n         Cache代理:

n         防火墙代理:

n         同步化代理:

n         智能引用代理:

n         功能代理:完成某些功能的时候需要一些附加的工作,这时候可以利用代理来进行处理。

 

 

2.  代理模式的结构

代理模式所涉及的角色有:

抽象主题角色:声明了真是主题和代理主题的共同接口,这样一来在任何时候可以使用真实代理主题的地方都可以使用代理主题。

代理主题角色:代理主题角色内部含有真实主题的引用,从而可以在任何使用操作真实主题对象;代理主题角色提供一个与真实主题角色相同的接口,以便可以在任何时候可以替代真实主题;控制真实主题的引用,负责需要的时候创建真实主题对象(和删除真实主题);代理主题角色通常在将客户端调用递给真实主题之前或之后,都要执行某个操作,而不是单纯地调用传递给真实主题对象。

真实主题角色:定义了代理角色所代表的真实主题。

       这里给出代理模式一个简单的UML图:


3.  代理模式的用法

这部门给出上面UML图中的代码:

抽象主题源码:

package com.zsw.proxy;

 

abstractpublicclass Subject {

   

    /**

     * 声明一个抽象的请求方法

     */

    abstractpublicvoid request();

}

 

真实主题:

package com.zsw.proxy;

 

publicclass RealSubject extends Subject {

   

    /**

     * 声明一个抽象的请求方法

     */

    publicvoid request(){

       System.out.println("-------------真实主题-------------");

    }

}

 

 

代理主题:

package com.zsw.proxy;

publicclass ProxySubject extends Subject {

    private RealSubject realSubject;

    public     

    }

   

    /**

     * 声明一个抽象的请求方法

     */

    publicvoid request(){

       preRequest();

       if(realSubject == null){

           realSubject = new RealSubject();

       }

        realSubject.request();

       postRequest();

    }

   

    privatevoid preRequest(){

       System.out.println("-------------请求前的操作-------------");

    }

   

    privatevoid postRequest(){

       System.out.println("-------------请求后的操作-------------");

    }

}

 

 

客户端:

package com.zsw.proxy;

publicclass Client {

    publicstaticvoid main(String[] args) {

       Subject subject = new ProxySubject();

       subject.request();

    }

}

 

使用代理的显著好处是,系统提供了向真实主题传递客户请求的控制。代理主题可以在向真实主题传递客户请求之前执行特定的操作,并决定是否将请求传递给真实主题;代理主题可以在向真实主题传递请求后执行另外的一些操作。

 

 

4.  代理模式的应用的场景

1)        Java中的反射与动态代理,Java语言通过在java.lang.reflect库中提供下面三个类直接支持代理:Proxy、InvocationHandler和Method。如果以后在开发项目中,需要对那个方法调用前后执行一些其他的方法,可以考虑使用此模式,例如:事务的打开与关闭。

2)        高老庄的故事,故事情节大家都熟悉在这就省略了….

悟空扮演并代替高三小姐,其中可以把高三小姐的神貌当做抽象角色,高三小姐本身是真实角色,孙悟空则是代理角色。其UML图如下:

 

悟空代替高三小姐去会见猪八戒。这就是代理模式的运用,具体的讲,这是保护代理模式的应用。只有代理对象认为合适的时候,才会将客户端的请求传递给真实主题对象。

3)        比如要创建一个系统开销很大的对象、或者被调用对象在远程主机上、或目标对象功能还不足以满足需求.

4)        Hibernate延迟加载所采用的设计模式,Hibernate关联映射是的知识,当A实体和B实体之间存在关联关系是,Hibernate模式启动延迟加载,当系统加载A实体时,A实体关联的B实体并没有被加载出来,A实体所关联的B实体全部都是代理对象----只有等到A实体正真需要访问B实体时,系统才会去数据库里抓取B实体所对应的记录,Hibernate的延迟加载充分体现了代理模式的优势。当实体加载A实体时,也许只需要访问A实体对应的记录,根本不会访问B实体对应的记录。如果不采用代理模式,系统需要加载A实体时,同时加载A实体所有关联实体,这是多么大的系统开销啊!,在这里情况下,代理模式可以显著的提高系统运行性能。

5)        Spring AOP代理的方法可以在执行目标对象的方法之前、之后插入一些通用的处理。代理模式可以为被代理对象添加一些额外的功能。

 

5.  代理模式的优缺点

1)        优点:

ü         提供系统运行的性能。

ü         可以为被代理对象添加一些额外的功能。

2).缺点

 

 

6.  参考资料

1)        《Java 与 模式》

2)        《企业级Java开发与架构专业程序员在实战中的蜕变》




待续.........