zoukankan      html  css  js  c++  java
  • 代理模式

    代理模式:在代理模式中,一个类代表另一个类的功能。这种类型的设计模式属于结构型模式。
    再代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。
    介绍
    意图:为其他对象提供一种代理以控制这个对象的访问。
    主要解决:在直接访问对象带来的问题,比如说:要访问的对象在远程机器上。在面向对象系统中,有些对象由于某些原因(比如对象的创建开销很大,或者默写操作需要安全控制,或者需要远程的访问),直接访问会给使用者或者系统结构带来很多麻烦,我们可以访问此对象时加上一个对此对象的访问层。
    何时使用:想在访问一个类时做一些控制。
    如何解决:增加中间层。
    关键代码:实现与代理类组合(下文例子中)。
    应用实例: 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、和装饰器模式的区别:装饰器模式为了增强功能,而代理模式是为了加以控制。

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

    静态代理:类结构

    /**
    * @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();
    }

    /**
    * @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("查询");
    }
    }

    /**
    * @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();
    }
    }


    /**
    * @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代码同上

    /**
    * @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;
    }
    }

    /**
    * @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();
    }
    }



  • 相关阅读:
    linux常用的一些命令
    C语言之初认识
    前端VUE基于gitlab的CI_CD
    【Github】在repo中添加其它repo: adding embedded git repository
    【Algorithm】Sorting Algorithm
    【gitbook】gitbook init报错解决
    8 款浏览器兼容性测试工具介绍,需要的赶紧收藏吧!
    软件测试适合女生吗?大厂内部测试人员这样说!
    6 大测试用例设计题详细整理— 助攻高薪求职之路!
    APP 兼容性测试之云测平台体验
  • 原文地址:https://www.cnblogs.com/ludengfu/p/9579871.html
Copyright © 2011-2022 走看看