什么是代理模式?
为对象提供一种代理以控制对这个对象的访问
举个例子:现在你要追一个女孩[doge],然后怕直接送礼物不会被接受,所以通过那个女孩的好友去送礼物,你就是那个帮你送礼物的好友就是代理类,你就是被代理类,或者说隐藏类
例子实现代码
首先代理类和被代理类的共同特征抽象为接口,接口是两者都需要实现的
/**
* 代理接口,代理者和隐藏者都要实现的接口,这是两者之间的共同特征
*/
public interface IGiveGift {
void giveDolls();
void giveFlowers();
}
首先是一个追求者类,也就是被代理类
/**
* 追求者类,就是被隐藏的类,代理者中拥有追求者类的对象,追求者类里面实现了接口,实现的具体方法是在代理者中调用的
*/
public class Pursuit implements IGiveGift {
SchoolGirl schoolGirl;
/**
* 把女孩作为追求者的构造方法参数初始化,明确追求者类(隐藏类)对于女孩的关系
* 反之却不然,女孩不知道代理类的存在
*/
public Pursuit(SchoolGirl schoolGirl) {
this.schoolGirl = schoolGirl;
}
@Override
public void giveDolls() {
System.out.println(schoolGirl.getName()+"送你洋娃娃");
}
@Override
public void giveFlowers() {
System.out.println(schoolGirl.getName()+"送你鲜花");
}
}
代理类,也就是帮你送礼物的那位
/**
* 代理类,表面上执行行为的就是这个代理类,实际上代理类调用了被隐藏的类
*/
public class Proxy implements IGiveGift{
Pursuit pursuit;
public Proxy(SchoolGirl schoolGirl){
//引用传递到隐藏类
pursuit=new Pursuit(schoolGirl);
}
@Override
public void giveDolls() {
pursuit.giveDolls();
}
@Override
public void giveFlowers() {
pursuit.giveFlowers();
}
}
客户端调用
/**
* 客户端调用的代码
*/
public class Main {
public static void main(String[] args) {
SchoolGirl girl = new SchoolGirl("zhang");
Proxy proxy = new Proxy(girl);
proxy.giveDolls();
proxy.giveFlowers();
}
}
这就是一个代理模式的简单实现,接下来说一说代理模式的应用场景
代理模式的应用
1、虚拟代理:需要创建开销很大的对象,通过代理模式中隐藏类来存放实例化需要
很长时间的真实对象,而通过代理类来执行操作,这样可以达到性能的最优化,提升用户体验。
eg:打开一个很多内容的HTML文件,里面有很多文字和图片,但是还是可以很快打开它,此时
先看到的是文字,然后图片一张一张下载后才能看到。那些未打开的图片框,就是通过虚拟代理来
替代了真实的图片(也就是显示的是代理类,等到隐藏类加载出来后再显示实际隐藏类),此时
代理存储了真实图片的路径和尺寸
2、安全代理:用来控制真实对象访问时的权限,一般用于对象应该有不同的访问权限的时候
3、智能指引:当调用真实的对象时,代理处理另一些事,如计算真实对象的引用次数,这样当
该对象没有引用时,可以自动释放它(垃圾回收器GC的引用计数算法),或当第一次引用一个持久
对象时,将他装入内存,或在访问一个实际对象前,检查是否已经锁定该对象,以确保其他对象
不能改变该对象。
4、一些业务场景:日志、监控、限流、缓存、环境隔离
以上是一些可能用到代理模式的场景, 接下来我们得知道为什么要用代理模式?代理模式有什么好处?
代理模式的优缺点
代理模式优点:
1、代理模式可以通过代理类来增加对访问隐藏对象的的访问业务逻辑控制,
被隐藏的业务类可以只关心自己的核心逻辑,非核心逻辑由代理类实现访问控制
2、易维护,核心逻辑、非核心逻辑的修改不会相互影响
3、对于调用者\用户而言,使用方式没有区别,可以做到低成本替换
缺点:
每个被代理类都需要有一个代理类,增加了代码量
文中例子出自程杰《大话设计模式》