欢迎关注微信公众号:互联网全栈架构
前言:最近写了几篇关于设计模式的文章,得到了各位朋友的热烈欢迎(如果阅读量在100左右也算热烈的话),在此先表示感谢!设计模式比较多,一共有23种,如果生硬地去背的话,略显枯燥,且效果也会打折扣,所以我试图对每一种设计模式都用一个成语来进行概括,比如:
一呼百应:对于观察者模式,当观察目标的状态发生改变时,所有的观察者都会得到通知,所以我用一呼百应来形容。
聚沙成塔:建造者模式,通过多个步骤才创建好一个对象,这颇有聚沙成塔、集腋成裘的意思。
责无旁贷:责任链模式,处理链条上的每个角色都需要处理好自己的逻辑,较为符合责无旁贷的意境。
当然,有时候用这样的成语来总结设计模式的特点也不一定准确,但它毕竟能够提供一种联想记忆,而且选用的成语多多少少还是有一定的相关性的,所以决定继续采用这样的方式来介绍设计模式的用法,欢迎大家关注,也欢迎多多与小编交流,后台私信即可。
今天,我们来看一下代理模式,它也是一个非常常用的设计模式,在JDK或者Spring源码中也随处可见。代理模式属于结构模式,按照惯例,我们先来看看它的定义:
Provide a surrogate or placeholder for another object to control access to it.
为其他对象提供一种代理,以控制对这个对象的访问。
因为在实际对象之前加了一个代理对象,所以我们可以使用代理对象来控制对实际对象的访问,从而实现一些额外的功能,比如延迟加载、权限控制等。代理模式主要包括以下几个角色:
抽象主题(Subject):定义了真实主题和代理主题的公共接口,这样的话,在任何可以使用真实主题的地方都可以采用代理主题。
真实主题(Real Subject):定义了代理主题所代表的真实对象。
代理主题(Proxy):维护一个对真实主题的引用,在调用真实对象的方法前后,可以执行一些额外的操作,从而可以对真实对象进行控制。
我们以图片加载为例来进行说明,比如网站加载一个图片的时候,在加载之前和加载完成之后都需要进行相应的增强处理,看看类似这样的场景,怎么用代理模式来实现:
先定义一下抽象主题接口,再定义真实主题和代理主题,并且都实现这个抽象主题接口,最后是客户端与代理对象交互,代理对象对方法进行了增强处理:
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代码,最后打印出以下结果,可以看到,真实主题对象的方法做了增强处理:
代理模式分为静态代理和动态代理,以上代码为静态代理的情况,主要是为了讲解代理模式的原理和使用方法,代理类在程序运行之前就已经定义编译完成;而动态代理基于反射技术,在运行时动态生成。本文主要是为了说明代理模式的概念和基本用法,对于动态代理,它主要分为JDK和CGLIB动态代理,后续再详细介绍,敬请期待。
都看到这里了,请帮忙一键三连啊,也就是点击文末的在看、点赞、分享,这样会让我的文章让更多人看到,也会大大地激励我进行更多的输出,谢谢!
鸣谢:
https://www.baeldung.com/java-proxy-pattern
推荐阅读: