三分钟带您搞懂代理模式

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


全文共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

有没有什么问题?

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

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

相关文章
|
3月前
|
设计模式 算法 前端开发
【面试题】什么是策略模式?用了策略模式之后,再也不用写那么多 if else 了,真香!
【面试题】什么是策略模式?用了策略模式之后,再也不用写那么多 if else 了,真香!
|
3天前
|
Java 程序员 容器
十分钟搞懂依赖注入
依赖注入(DI)是软件开发中的关键技术,它将类的依赖关系转移至外部管理,提升了代码的模块化和可测试性。如同炒菜时调料不由厨师直接添加,而是由调料师准备并递送,程序员只需声明所需依赖,外部机制如DI容器会负责实例化并注入这些依赖。这样,类变得更灵活且易于测试,同时也促进了代码的模块化。例如,在Java中,可以通过构造函数注入Logger接口的不同实现(如ConsoleLogger和FileLogger),使Application类与其具体实现解耦。
|
3月前
|
设计模式 Java
【设计模式】腾讯二面:自动贩卖机/音频播放器使用了什么设计模式?
【设计模式】腾讯二面:自动贩卖机/音频播放器使用了什么设计模式?
35 1
|
3月前
|
设计模式 Java 开发者
一目了然!谁能想到Java多线程设计模式竟然被图解,看完不服不行
多线程设计模式在Java编程中起着至关重要的作用,它能够有效提高程序的执行效率,使得程序在处理大量数据和复杂任务时更加高效。然而,对于初学者来说,理解和应用多线程设计模式可能是一项相当具有挑战性的任务。为了让读者更加轻松地掌握这一复杂主题,我们带着一种全新的图解方式,深入剖析Java多线程设计模式的精髓。
|
设计模式 缓存 安全
2023-6-29-第十一式代理模式
2023-6-29-第十一式代理模式
62 0
|
设计模式 缓存 人工智能
设计模式篇之一文搞懂如何实现单例模式(二)
设计模式篇之一文搞懂如何实现单例模式(二)
|
设计模式 安全 Java
设计模式篇之一文搞懂如何实现单例模式(一)
设计模式篇之一文搞懂如何实现单例模式(一)
|
设计模式 缓存 人工智能
设计模式篇之一文搞懂如何实现单例模式
设计模式篇之一文搞懂如何实现单例模式
阿里面试官:使用策略模式+工厂模式干掉代码中过多的if-else
过多if-else项目背景 如果一开始就知道现在的业务需要,大部分人都不会在代码里添加过多的if-else判断的,烂代码基本都是刚开始写代码时并没有太多的需求,随着期需求不断的修改增加,开发时间也较的紧张,代码往往都是怎么快速怎么写。当然多写一个if-else比使用各种设计模式肯定来的更快速了,这也就导致项目代码慢慢变得臃肿,难以维护的主要原因。在有空闲时间的情况下就可以给以前的代码做一次手术了。先看本次未优化前的代码:
|
设计模式 监控 Java
代理模式看这一篇就够了~
代理模式看这一篇就够了~
662 1
代理模式看这一篇就够了~