越俎代庖:应用广泛的代理模式

欢迎关注微信公众号:互联网全栈架构

前言:最近写了几篇关于设计模式的文章,得到了各位朋友的热烈欢迎(如果阅读量在100左右也算热烈的话),在此先表示感谢!设计模式比较多,一共有23种,如果生硬地去背的话,略显枯燥,且效果也会打折扣,所以我试图对每一种设计模式都用一个成语来进行概括,比如:

一呼百应:对于观察者模式,当观察目标的状态发生改变时,所有的观察者都会得到通知,所以我用一呼百应来形容。

聚沙成塔:建造者模式,通过多个步骤才创建好一个对象,这颇有聚沙成塔、集腋成裘的意思。

责无旁贷:责任链模式,处理链条上的每个角色都需要处理好自己的逻辑,较为符合责无旁贷的意境。

当然,有时候用这样的成语来总结设计模式的特点也不一定准确,但它毕竟能够提供一种联想记忆,而且选用的成语多多少少还是有一定的相关性的,所以决定继续采用这样的方式来介绍设计模式的用法,欢迎大家关注,也欢迎多多与小编交流,后台私信即可。

今天,我们来看一下代理模式,它也是一个非常常用的设计模式,在JDK或者Spring源码中也随处可见。代理模式属于结构模式,按照惯例,我们先来看看它的定义:

Provide a surrogate or placeholder for another object to control access to it.

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

因为在实际对象之前加了一个代理对象,所以我们可以使用代理对象来控制对实际对象的访问,从而实现一些额外的功能,比如延迟加载、权限控制等。代理模式主要包括以下几个角色:

抽象主题(Subject):定义了真实主题和代理主题的公共接口,这样的话,在任何可以使用真实主题的地方都可以采用代理主题。

真实主题(Real Subject):定义了代理主题所代表的真实对象。

代理主题(Proxy):维护一个对真实主题的引用,在调用真实对象的方法前后,可以执行一些额外的操作,从而可以对真实对象进行控制。

437e7bb7cba45e70ff50fe51e6dc5bd1.png

我们以图片加载为例来进行说明,比如网站加载一个图片的时候,在加载之前和加载完成之后都需要进行相应的增强处理,看看类似这样的场景,怎么用代理模式来实现:

先定义一下抽象主题接口,再定义真实主题和代理主题,并且都实现这个抽象主题接口,最后是客户端与代理对象交互,代理对象对方法进行了增强处理:

package com.sample.patterns.proxy;
// 图片抽象主题
public interface ImageSubject {
    void request();
}
package com.sample.patterns.proxy;
// 大图片加载,真实主题对象
public class LargeImageSubject implements ImageSubject{
    @Override
    public void request() {
        // 实际的业务逻辑处理
        System.out.println("Large image loaded!");
    }
}
package com.sample.patterns.proxy;
// 代理对象
public class ImageSubjectProxy implements ImageSubject{
    // 持有一个真实对象的引用
    private LargeImageSubject largeImageSubject;
    @Override
    public void request() {
        if(largeImageSubject == null){
            largeImageSubject = new LargeImageSubject();
        }
        // 调用真实对象的处理方法前后,可以做一些增强操作
        System.out.println("Do something before invoke");
        largeImageSubject.request();
        System.out.println("Do something after invoke");
    }
}
package com.sample.patterns.proxy;
// 客户端与代理对象进行交互
public class Client {
    public static void main(String[] args) {
        // 创建一个代理对象
        ImageSubject imageSubject = new ImageSubjectProxy();
        imageSubject.request();
    }
}

运行Client代码,最后打印出以下结果,可以看到,真实主题对象的方法做了增强处理:

5345af77327e517bbf615f39bd09ffba.png

代理模式分为静态代理和动态代理,以上代码为静态代理的情况,主要是为了讲解代理模式的原理和使用方法,代理类在程序运行之前就已经定义编译完成;而动态代理基于反射技术,在运行时动态生成。本文主要是为了说明代理模式的概念和基本用法,对于动态代理,它主要分为JDK和CGLIB动态代理,后续再详细介绍,敬请期待。

都看到这里了,请帮忙一键三连啊,也就是点击文末的在看、点赞、分享,这样会让我的文章让更多人看到,也会大大地激励我进行更多的输出,谢谢!

鸣谢:

https://www.baeldung.com/java-proxy-pattern

推荐阅读:

MySQL整数类型的长度到底是什么含义?

漫谈MySQL中的事务

臭名昭著,怙恶不悛的OOM,到底是什么?

俯拾皆是的Java注解,你真的get了吗?

“八面玲珑”的ZooKeeper入门介绍

责无旁贷:超酷的责任链模式

聚沙成塔:聊聊建造者模式

公司裁员,码农竟然成了“帮凶”?(剧情杜撰)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值