经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » 设计模式 » 查看文章
代理模式
来源:cnblogs  作者:DouglasKey  时间:2018/9/25 20:18:43  对本文有异议

代理模式:在代理模式中,一个类代表另一个类的功能。这种类型的设计模式属于结构型模式。
再代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。
介绍
意图:为其他对象提供一种代理以控制这个对象的访问。
主要解决:在直接访问对象带来的问题,比如说:要访问的对象在远程机器上。在面向对象系统中,有些对象由于某些原因(比如对象的创建开销很大,或者默写操作需要安全控制,或者需要远程的访问),直接访问会给使用者或者系统结构带来很多麻烦,我们可以访问此对象时加上一个对此对象的访问层。
何时使用:想在访问一个类时做一些控制。
如何解决:增加中间层。
关键代码:实现与代理类组合(下文例子中)。
应用实例: 1、Windows 里面的快捷方式。
2、相比于中介,买家找房子,闲麻烦,找个委托中介找房
3、买火车票不一定在火车站买,也可以去代售点。
4、一张支票或银行存单是账户中资金的代理。支票在市场交易中来代替现金,并提供对签发人账号上资金的控制。
5、Spring Aop(重点)。
优点: 1、职责清晰。
2、高扩展性。
3、智能化。
缺点: 1、由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。
2、实现代理模式需要额外的工作,有些代理模式的实现非常复杂。
使用场景
按职责来划分,通常有以下场景:
1、远程代理。
2、虚拟化代理。
3、Copy-on-Write 代理。
4、保护(Protect or Access)代理。
5、Cache 代理。
6、防火墙(Firewall)代理。
7、同步化(Synchroniztion)代理 。
8、智能引用代理。
注意事项: 1、和适配器模式的区别:适配器模式主要改变所考虑对象的接口,而代理模式不能改变所代理类的接口。 2、和装饰器模式的区别:装饰器模式为了增强功能,而代理模式是为了加以控制。

代码实例:代理模式 分为动态代理和静态代理,我们在开发中使用动态代理,因为动态两个字听起来牛逼!

静态代理:类结构

 

  1. /**
    * @author xxx-001.
    * @date 2018/9/3.
    * @time 8:47.
    * @Description 抽象接口
    */
    public interface Demo {

    /**
    * @Author: xxx
    * @Date: 8:48
    * @Param: No such property: code for class: Script1
    * @return:
    * @Description:增加
    */
    void add();

    /**
    * @Author: xxx
    * @Date: 8:48
    * @Param: No such property: code for class: Script1
    * @return:
    * @Description:删除
    */
    void delete();

    /**
    * @Author: xxx
    * @Date: 8:48
    * @Param: No such property: code for class: Script1
    * @return:
    * @Description:修改
    */
    void update();

    /**
    * @Author: xxx
    * @Date: 8:49
    * @Param: No such property: code for class: Script1
    * @return:
    * @Description:查询
    */
    void select();
    }

  1. /**
    * @author xxx-001.
    * @date 2018/9/3.
    * @time 8:44.
    * @Description 委托类
    */
    public class EntrustDemo implements Demo {

    @Override
    public void add() {
    System.out.println("添加");
    }

    @Override
    public void delete() {
    System.out.println("删除");
    }

    @Override
    public void update() {
    System.out.println("修改");
    }

    @Override
    public void select() {
    System.out.println("查询");
    }
    }

  1. /**
    * @author xxx-001.
    * @date 2018/9/3.
    * @time 8:46.
    * @Description 代理类
    */
    public class ProxyDemo implements Demo {

    /**
    * 委托对象
    */
    private EntrustDemo entrustDemo;

    /**
    * 构造函数
    *
    * @param entrustDemo
    */
    public ProxyDemo(EntrustDemo entrustDemo) {
    this.entrustDemo = entrustDemo;
    }

    /**
    * 代理类处理
    */
    @Override
    public void add() {
    System.out.println("代理添加");
    }

    @Override
    public void delete() {
    System.out.println("代理删除");
    }

    /**
    * 引用委托处理
    */
    @Override
    public void update() {
    entrustDemo.update();
    }

    @Override
    public void select() {
    entrustDemo.select();
    }
    }


  1. /**
    * @author xxx-001.
    * @date 2018/9/3.
    * @time 8:49.
    * @Description 测试类
    */
    public class TestDemo {
    public static void main(String[] args) {
    //委托对象
    EntrustDemo entrustDemo = new EntrustDemo();
    //使用静态代理对象
    ProxyDemo proxyDemo = new ProxyDemo(entrustDemo);

    //通过代理对象实现对委托类的调用
    proxyDemo.add();
    proxyDemo.delete();
    proxyDemo.update();
    proxyDemo.select();
    }
    }

动态代理:

 

Demo类代码和EntrustDemo代码同上

  1. /**
    * @author xxx-001.
    * @date 2018/9/3.
    * @time 8:46.
    * @Description 代理类
    */
    public class ProxyHandlerDemo implements InvocationHandler {

    /**
    * 委托对象
    */
    private EntrustDemo entrustDemo;

    /**
    * 构造方法
    *
    * @param entrustDemo
    */
    public ProxyHandlerDemo(EntrustDemo entrustDemo) {
    this.entrustDemo = entrustDemo;
    }

    /**
    * invoke的三个参数、第一个参数就是代理者,如果你想对代理者做一些操作可以使用这个参数;第二个就是被执行的方法,第三个是执行该方法所需的参数。
    * 当你执行代理者的某个方法的时候,最后跑的都是invoke方法。
    * @param proxy
    * @param method
    * @param args
    * @return
    * @throws Throwable
    */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    System.out.println("你好,开始");

    if (method.getName().equals("add")) {
    method.invoke(entrustDemo, args);
    }
    if (method.getName().equals("delete")) {
    method.invoke(entrustDemo, args);
    }
    if (method.getName().equals("update")) {
    method.invoke(entrustDemo, args);
    }
    if (method.getName().equals("select")) {
    method.invoke(entrustDemo, args);
    }

    System.out.println("谢谢,再见");

    return null;
    }
    }

  1. /**
    * @author xxx-001.
    * @date 2018/9/3.
    * @time 8:49.
    * @Description 测试类
    */
    public class TestDemo {
    public static void main(String[] args) {
    //委托对象
    EntrustDemo entrustDemo = new EntrustDemo();
    //使用JDK自带的实现代理接口
    InvocationHandler handler = new ProxyHandlerDemo(entrustDemo);

    //通过Proxy的newProxyInstance方法来创建我们的代理对象
    Demo demo = (Demo) Proxy.newProxyInstance(handler.getClass().getClassLoader(), entrustDemo.getClass().getInterfaces(), handler);

    //通过代理对象实现对委托类的调用
    demo.add();
    demo.delete();
    demo.select();
    demo.update();
    }
    }

 



 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号