三分钟带您搞懂代理模式

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


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

有没有什么问题?

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

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

相关文章
|
8月前
|
设计模式 Java 程序员
谈谈代码:漫谈代理模式
代理模式是在编程中非常常见的设计模式.笔者在面试的过程中也经常会问到相关的问题,但是很多同学答的并不尽人意
72 0
谈谈代码:漫谈代理模式
|
8月前
|
设计模式 XML JSON
二十三种设计模式全面解析-代理模式进阶篇:揭秘远程代理
二十三种设计模式全面解析-代理模式进阶篇:揭秘远程代理
168 0
|
8月前
|
设计模式 Java
Java设计模式【十二】:亨元模式
Java设计模式【十二】:亨元模式
61 0
|
5月前
|
Java 程序员 容器
十分钟搞懂依赖注入
依赖注入(DI)是软件开发中的关键技术,它将类的依赖关系转移至外部管理,提升了代码的模块化和可测试性。如同炒菜时调料不由厨师直接添加,而是由调料师准备并递送,程序员只需声明所需依赖,外部机制如DI容器会负责实例化并注入这些依赖。这样,类变得更灵活且易于测试,同时也促进了代码的模块化。例如,在Java中,可以通过构造函数注入Logger接口的不同实现(如ConsoleLogger和FileLogger),使Application类与其具体实现解耦。
|
5月前
|
设计模式
设计模式的基础问题之代理模式在工作中的问题如何解决
设计模式的基础问题之代理模式在工作中的问题如何解决
|
8月前
|
设计模式 Java
Java设计模式【十三】:代理模式
Java设计模式【十三】:代理模式
36 0
|
设计模式 缓存 安全
2023-6-29-第十一式代理模式
2023-6-29-第十一式代理模式
78 0
|
设计模式 监控 Java
代理模式看这一篇就够了~
代理模式看这一篇就够了~
687 1
|
Java 数据库连接 数据库
信不信十分钟让你彻底搞懂java反射
概念:反射是Java的一种机制,让我们可以在运行时获取类的信息 作用:通过反射,我们可以在程序运行时动态创建对象,还能获取到类的所有信息,比如它的属性、构造器、方法、注解等;
18172 2
信不信十分钟让你彻底搞懂java反射
|
设计模式 Android开发
彻底明白Android设计模式—(动态)代理模式
代理模式其实就是提供了对目标对象的另外的访问方式,通过代理对象访问目标对象 为啥要这么麻烦呢!!!其实是为了不去修改原有的代码,通过代理也可以访问这个对象而且可以进行扩展
389 1

热门文章

最新文章