三分钟带您搞懂代理模式

简介: 三分钟带您搞懂代理模式


全文共1439字,预计阅读时间:10分钟

定义:

  代理模式(Proxy),为其他对象提供一种代理以控制对这个对象的访问。

  代理模式是一种比较贴近于生活的 设计模式,现实生活中也有很多代理模式的例子:

  1. 住酒店不一定需要亲自到酒店去,还可以通过微信支付下的同程艺龙来订酒店。
  2. 我们可以通过中介去找房子,不用直接跟房东沟通(现实生活中,我们更希望直接跟房东沟通)
  3. 春运买票买不到,我们可以找黄牛替我们抢票
  4. 想访问国外的网站,可以使用代理服务器进行访问。

  代理模式通常解决的问题是,我们没有办法直接访问某一个对象,但是却想使用这个对象的一些功能,这个时候我们就可以创建一个代理对象,通过访问代理对象,间接的访问这个对象。

  我们想去旅行,但是没有办法提前去目的地订酒店,所以我们通过同程艺龙来订酒店。同程艺龙就是一个代理对象,他和酒店一样,提供了订酒店的方法。

  我们没有渠道去直接联系房东,所以我们可以通过中介公司租房,房东把租房这件事委托给了中介公司,这里中介公司就是一个代理对象。代理对象除了调用真实对象的方法,还可以对方法进行增强。比如中介公司可以赚差价。

图解:

  这里可以看出,无论是代理对象和被代理对象,都实现了Subject接口,同时被代理对象作为代理对象的成员变量。这个结构与装饰模式非常像,下图是装饰模式的示意图:

那么它们之间有什么区别呢?

  首先从定义上可以看出,装饰模式强调的是添加职责,而代理模式强调的是间接访问。

  其次从结构设计上来说,装饰模式是将一个个功能进行拆分,使用时再动态的进行组装,生成不同功能的对象。而代理模式却是在编译之前就已经确定了代理对象和被代理对象之间的关系。

  最后就使用上来说,装饰模式需要客户端去组装对象,而代理模式却只需要客户端去调用代理对象,代理对象和被代理对象的关系被封装到了代理对象中,对用户而言是无感的。

实例:

  这里举一个订酒店的实例,小赵在同程艺龙上预定了橘子酒店,这里酒店就是图中的Subject,它提供了订酒店、付款的方法,橘子酒店就是RealSubject,它是酒店的一个具体实现。而同程艺龙作为酒店的代理,提供优质的客户服务,其中包括订酒店前的电话确认、订酒店后的客户回访、付款时提供红包减免等。

代码:

/**
 * 酒店.
 *
 * @author jialin.li
 * @date 2019-12-27 11:37
*/
public interface Hotel {
    /** 订酒店 **/
    void hotelBooking(String name);
    /** 付款 **/
    double pay();
}
/**
 * 橘子酒店.
 *
 * @author jialin.li
 * @date 2019-12-27 13:17
*/
public class OrangeHotel implements Hotel {
    @Override
    public void hotelBooking(String name) {
        System.out.println(name + ",欢迎入住橘子酒店");
    }
    @Override
    public double pay() {
        return 120d;
    }
}
/**
 * 同程艺龙
 *
 * @author jialin.li
 * @date 2019-12-27 13:20
*/
public class Elong implements Hotel{
    private Hotel hotel;
    public Elong() {
        hotel = new OrangeHotel();
    }
    @Override
    public void hotelBooking(String name) {
        System.out.println(confirm(name));
        hotel.hotelBooking(name);
        System.out.println(callback(name));
    }
    @Override
    public double pay() {
        return useHongbao(hotel.pay());
    }
    private String confirm(String name){
        return "亲爱的"+name+"您预定了橘子酒店,记得入住哦!";
    }
    private String callback(String name){
        return "亲爱的"+name+"您的入住已经结束,有问题请及时反馈!";
    }
    private double useHongbao(double price){
        return price - 50.0d;
    }
}
/**
 * 测试类.
 *
 * @author jialin.li
 * @date 2019-12-27 13:36
*/
public class Main {
    public static void main(String[] args) {
        String xiaozhao = "小赵";
        Elong elong = new Elong();
        elong.hotelBooking(xiaozhao);
        System.out.print("共花费了:");
        System.out.println(elong.pay());
    }
}

结果:

亲爱的小赵您预定了橘子酒店,记得入住哦!

小赵,欢迎入住橘子酒店

亲爱的小赵您的入住已经结束,有问题请及时反馈!

共花费了:70.0

有没有什么问题?

  可以看出,我们在代理类中直接引用了被代理对象,所以代理类和被代理类是一种一对一的关系,即我们需要为每一个被代理类,创建一个代理类。

  假设我们现在有一个打点的需求,要为系统中的一批对象增加记录日志的方法,如果使用代理模式,就要为这一批对象创建代理类,这样的工作量是无疑是巨大的。那么有没有什么办法可以让我们可以少写或者不写代理类,却能完成代理功能呢?这就要引出了我们要讲的一个概念——动态代理(动态代理涉及到、反射类加载的一些知识,所以在下一篇文章中讲解)

相关文章
|
1月前
|
设计模式 算法 前端开发
【面试题】什么是策略模式?用了策略模式之后,再也不用写那么多 if else 了,真香!
【面试题】什么是策略模式?用了策略模式之后,再也不用写那么多 if else 了,真香!
|
1月前
|
设计模式 Java
【设计模式】腾讯二面:自动贩卖机/音频播放器使用了什么设计模式?
【设计模式】腾讯二面:自动贩卖机/音频播放器使用了什么设计模式?
29 1
|
1月前
|
设计模式 Java 开发者
一目了然!谁能想到Java多线程设计模式竟然被图解,看完不服不行
多线程设计模式在Java编程中起着至关重要的作用,它能够有效提高程序的执行效率,使得程序在处理大量数据和复杂任务时更加高效。然而,对于初学者来说,理解和应用多线程设计模式可能是一项相当具有挑战性的任务。为了让读者更加轻松地掌握这一复杂主题,我们带着一种全新的图解方式,深入剖析Java多线程设计模式的精髓。
|
10月前
|
设计模式 缓存 Java
从没有人将代理模式分析得如此透彻
举个例子,有些人到了适婚年龄,会被父母催婚。而现在在各种压力之下,很多人都选择晚婚晚育。于是着急的父母就开始到处为子女相亲,比子女自己还着急。下面来看代码实现。创建顶层接口IPerson的代码如下。
29 0
从没有人将代理模式分析得如此透彻
|
10月前
|
设计模式 缓存 安全
2023-6-29-第十一式代理模式
2023-6-29-第十一式代理模式
56 0
|
数据采集 算法 C++
库调多了,都忘了最基础的概念-《单例模式VS状态码》
库调多了,都忘了最基础的概念-《单例模式VS状态码》
66 0
库调多了,都忘了最基础的概念-《单例模式VS状态码》
阿里面试官:使用策略模式+工厂模式干掉代码中过多的if-else
过多if-else项目背景 如果一开始就知道现在的业务需要,大部分人都不会在代码里添加过多的if-else判断的,烂代码基本都是刚开始写代码时并没有太多的需求,随着期需求不断的修改增加,开发时间也较的紧张,代码往往都是怎么快速怎么写。当然多写一个if-else比使用各种设计模式肯定来的更快速了,这也就导致项目代码慢慢变得臃肿,难以维护的主要原因。在有空闲时间的情况下就可以给以前的代码做一次手术了。先看本次未优化前的代码:
|
设计模式 监控 Java
代理模式看这一篇就够了~
代理模式看这一篇就够了~
657 1
代理模式看这一篇就够了~
|
Java 测试技术 Maven
花了2个钟才搞懂这AOP为啥没生效,水友却睡着了……
Springboot中AOP失效的原因 今天 4ye 来和小伙伴们分享一个小实战啦 ,冲冲冲~ (。・∀・)ノ 实战回顾 (我居然拖到现在才写了这文章…… 😵) 主要是在一个周日(2020.6.6)在技术群里看到一个老哥在问 “怎么用切面来捕获自定义异常?” ( ̄▽ ̄)" 我当时想的是,捕获异常不是很常见的吗,平时经常用到这个全局异常捕获 ,于是就把自己 GitHub 上的小例子发给他(主要是这个 ControllerAdvice 注解),如图 👇 结果老哥过了一段时候就加了我,还问我有没有空帮忙看下,还
246 0
|
Java 数据库连接 数据库
信不信十分钟让你彻底搞懂java反射
概念:反射是Java的一种机制,让我们可以在运行时获取类的信息 作用:通过反射,我们可以在程序运行时动态创建对象,还能获取到类的所有信息,比如它的属性、构造器、方法、注解等;
17884 2
信不信十分钟让你彻底搞懂java反射