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

    首先我们通过一张图来说明什么是代理模式(后面会有具体的实例):

    什么是代理模式?

    定义:客户端(Client)不直接调用真实对象,而是通过调用代理对象去调用真实对象。

    为什么要用代理模式?:

    在某些情况下,一个对象不适合或者不能直接引用另一个对象,使用代理模式起到了中介和保护真实对象的作用,同时提高了扩展性,举个例子吧,好比你买火车票不一定要在火车站买,可以在代售点买,代售点也不一定只卖火车票,还可以扩展业务,卖飞机票,汽车票等。

    优缺点?

    优点: 1、职责清晰。 2、高扩展性。 3、起到了中介的作用和保护了真实对象的作用。

    缺点: 1、由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。 2、实现代理模式需要额外的工作,有些代理模式的实现非常复杂。

    应用实例: 

    1、Windows 里面的快捷方式(Windows桌面上那些五颜六色的图标,快捷方式是Windows提供的一种快速启动程序、打开文件或文件夹的方法。它是应用程序的快速连接。)。

    2、买火车票不一定在火车站买,也可以去代售点买

    3、Spring AOP(动态代理)。

    和适配器模式和装饰器模式的区别

    1、和适配器模式的区别:适配器模式主要改变所考虑对象的接口,而代理模式不能改变所代理类的接口。

    2、和装饰器模式的区别:装饰器模式为了增强功能,而代理模式是为了加以控制。

    模式结构

    一个是真正的你要访问的对象(目标类),一个是代理对象,真正对象与代理对象实现同一个接口,先访问代理类再访问真正要访问的对象。

    代理模式分为静态代理、动态代理。

    静态代理 在程序运行前就事先写好代理类,可以手工编写也可以使用工具生成,缺点是每个业务类都要对应一个代理类,特别不灵活也不方便,于是就有了动态代理。

    动态代理 程序在运行期间动态构建代理对象和动态调用代理方法的一种机制,实现方式有JDK ProxyCGLib(Code Generation Library)两种。

    实例分析

    抽象接口:

    package Proxy;
    /** * @author 佛大java程序员 * @since 1.0.0 */ public interface Image { void display(); }

    真实对象:

    package Proxy;
    
    /**
     * @author 佛大java程序员
     * @since 1.0.0
     */
    public class RealImage implements Image {
    
        private String fileName;
    
        public RealImage(String fileName){
            this.fileName = fileName;
            loadFromDisk(fileName);
        }
    
        @Override
        public void display() {
            System.out.println("Displaying " + fileName);
        }
    
        private void loadFromDisk(String fileName){
            System.out.println("Loading " + fileName);
        }
    }

    代理对象:

    package Proxy;
    
    /**
     * @author 佛大java程序员
     * @since 1.0.0
     */
    public class ProxyImage implements Image{
    
        private RealImage realImage;
        private String fileName;
    
        public ProxyImage(String fileName){
            this.fileName = fileName;
        }
    
        @Override
        public void display() {
            if(realImage == null){
                realImage = new RealImage(fileName);
            }
            realImage.display();
        }
    }

    客户端(Client):

    package Proxy;
    
    /**
     * @author 佛大java程序员
     * @since 1.0.0
     */
    public class Client {
        public static void main(String[] args) {
            Image image = new ProxyImage("佛大java程序员.jpg");
    
            // 图像将从磁盘加载
            image.display();
            System.out.println("");
            // 图像不需要从磁盘加载
            image.display();
        }

    运行结果:

    常见面试题:

    (1)为什么要用代理模式?

    参考:

    百度百科 -- 代理模式

    https://baike.baidu.com/item/%E4%BB%A3%E7%90%86%E6%A8%A1%E5%BC%8F/8374046?fr=aladdin

    菜鸟教程 --  代理模式

    https://www.runoob.com/design-pattern/proxy-pattern.html

    掘金 --  3种代理模式-理解Spring Aop

    https://juejin.im/post/5cea0180e51d4550bf1ae7db#heading-3

    静态代理其实就是事先写好代理类,可以手工编写也可以使用工具生成,但它的缺点是每个业务类都要对应一个代理类,特别不灵活也不方便,于是就有了动态代理。

    希望本文章对您有帮助,您的转发、点赞是我的创作动力,十分感谢。更多好文推荐,请关注我的微信公众号--JustJavaIt
  • 相关阅读:
    2020年3月15日python学习笔记——变量的创建过程 垃圾回收机制 变量的指向关系
    2020年3月14日python学习笔记——学习实操的程序(第一小章)--------------------重要
    2020年3月14日python学习笔记——break ,continue,while ...else....
    2020年3月14日python学习笔记——流程控制语句(if else ,while)
    2020年3月14日python学习笔记——算数运算、比较运算、逻辑运算、赋值运算
    2020年3月14日python学习笔记——列表 输入命令符
    Ubuntu 安装mysql和修改字符编码
    死锁与递归锁
    守护线程
    线程
  • 原文地址:https://www.cnblogs.com/liaowenhui/p/12593162.html
Copyright © 2011-2022 走看看