设计模式之代理模式(Proxy Pattern)
定义:在代理模式中,一个类代表另一个类的功能。这种类型的设计模式属于结构型模式。在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。
代理模式的主要意图就是为其他对象提供一种代理来控制对这个对象的访问。
解决问题:在直接访问对象时带来的问题,比如说:要访问的对象在远程的机器上。在面向对象系统中,有些对象由于某些原因,直接访问会给使用者或者系统结构带来很多麻烦,我们可以在访问此对象时加上一个对此对象的访问层。
区分:
1、和适配器模式的区别:适配器模式主要改变所考虑对象的接口,而代理模式不能改变所代理类的接口。
2、和装饰器模式的区别:装饰器模式为了增强功能,而代理模式是为了加以控制。
细分类:
1、远程代理:将工作委托给远程对象,不同的进程,不同机器来完成,例如企业Bean。
2、保护代理:主要进行安全检查或者权限检查
3、缓存代理:使用存储来加速调用,例如Spring的@Cacheable方法
4、虚拟和智能代理:这种模式为方法增加了功能,例如记录性能指标,或者进行延迟初始化。
应用场景:
1、当我们想要隐藏某个类时,可以为其提供代理类
2、当一个类需要对不同的调用者提供不同的调用权限时,可以使用代理类来实现
3、当我们要扩展某个类的某个功能时,可以使用代理模式,在代理类中进行简单扩展(只针对简单扩展,可在引用委托类的语句之前与之后进行)
策略模式中的角色:
1、Subject(共同接口):客户端使用的现有接口
2、RealSubJect(真实对象):真实对象或者目标对象
3、ProxySubject(代理对象):代理对象
代理模式的优点:
1、能将代理对象与目标对象进行分离。
2、一定程度上降低了系统的耦合度,扩展性好。
3、可以起到保护目标对象的作用。
4、可以对目标对象的功能增强。
代理模式的缺点:
1、代理模式会造成系统设计中类的数量增加。
2、在客户端和目标对象增加一个代理对象,会造成请求处理速度变慢。
3、增加了系统的复杂度。
案例:代理模式之王婆牵媒
西门庆找潘金莲,那潘金莲不好意思答复,咋办,通过隔壁王婆做个媒人
UML类图:
JAVA代码实现
1、定义一种类型的女人,王婆和潘金莲都属于这个类型
package com.dzghyd.designmode.proxy;
/**
* 定义一种类型的女人,王婆和潘金莲都属于这个类型
*/
public interface BadWomen {
//抛媚眼
public void makeEyesWithMan();
//做羞羞的事
public void happyWithMan();
}
2、定义潘金莲类,两个方法:1、抛媚眼 2、做羞羞的事
package com.dzghyd.designmode.proxy.impl;
import com.dzghyd.designmode.proxy.BadWomen;
/**
* 定义潘金莲类,两个方法:1、抛媚眼 2、做羞羞的事
*/
public class PanJinLian implements BadWomen {
@Override
public void makeEyesWithMan() {
System.out.println("潘金莲抛媚眼");
}
@Override
public void happyWithMan() {
System.out.println("潘金莲在和男人做羞羞的事.....");
}
}
3、定义王婆类,她太老了,男人都看不上,但是她有智慧有经验呀,她作为这类女人的代理
package com.dzghyd.designmode.proxy.impl;
import com.dzghyd.designmode.proxy.BadWomen;
/**
* 王婆类,她太老了,男人都看不上,但是她有智慧有经验呀,她作为这类女人的代理
*/
public class WangPo implements BadWomen {
private BadWomen badWomen;
public WangPo(){ //默认的话,是潘金莲的代理
this.badWomen = new PanJinLian();
}
//她可以是BadWomen的任何一个女人的代理,只要你是这一类型就可以
public WangPo(BadWomen badWomen){
this.badWomen = badWomen;
}
//自己老了,可以让年轻的代替
public void happyWithMan() {
this.badWomen.happyWithMan();
}
public void makeEyesWithMan() {
this.badWomen.makeEyesWithMan();
}
}
4、接下来就是西门去类,找王婆做媒
package com.dzghyd.designmode.proxy;
import com.dzghyd.designmode.proxy.impl.WangPo;
/**
* 西门庆类,相当于调用者,这里找王婆做媒
*/
public class XiMenQing {
public static void main(String[] args) {
//叫王婆出来
WangPo wangPo = new WangPo();
//然后西门庆找王婆作媒,虽然表面上时王婆在做媒,实际上交互对象是潘金莲
wangPo.makeEyesWithMan();
wangPo.happyWithMan();
}
}
5、运行结果: