代理模式(Proxy)
意图
为其他对象提供一种代理以控制对这个对象的访问,可以简单理解为:在开发中,由于某些原因,
客户端不想或不能直接访问一个对象,此时可以通过一个称之为“代理”的第三者来实现间接访问,该方案对应的设计模式被称为代理模式。
适用性
1、远程代理:为一个位于不同的地址空间的对象提供一个本地的代理对象,这个不同的地址空间可以是在同一台主机中,也可是在另一台主机中,远程代理又称为大使(Ambassador)。
2、虚拟代理:如果需要创建一个资源消耗较大的对象,先创建一个消耗相对较小的对象来表示,真实对象只在需要时才会被真正创建。
3、保护代理:控制对一个对象的访问,可以给不同的用户提供不同级别的使用权限。
4、缓冲代理:某一个目标操作的结果提供临时的存储空间,以便多个客户端可以共享这些结果。
5、智能引用代理:当一个对象被引用时,提供一些额外的操作,例如将对象被调用的次数记录下来等。
结构
Proxy
保存一个引用使得代理可以访问实体
提供一个与Subject的接口相同的接口,正阳代理就可以用来替代实体
控制对实体的存取,并可能负责创建和删除它
Subject
定义RealSubject和Proxy的共用接口
RealSubject
定义Proxy所代表的实体
实现
由于IphoneXS首发在美帝,你想买一下美版,但是由于没有途径,你选择了代购,通过代购来购买
Subject(声明需要代理做的事情)
package proxy;
/**
* @Author fitz.bai
* @Date 2018/8/31 14:30
*/
public interface Subject {
void buyIphoneXS();
}
RealSubject(具体到代理人)
package proxy;
/**
* @Author fitz.bai
* @Date 2018/8/31 14:31
*/
public class RealSubject implements Subject {
@Override
public void buyIphoneXS() {
System.out.println("抢购IphoneXS");
}
}
Proxy(代购行动,通过代理类创建真实实例并访问其方法,还提供其他操作)
package proxy;
/**
* @Author fitz.bai
* @Date 2018/8/31 14:31
*/
public class Proxy implements Subject {
@Override
public void buyIphoneXS() {
RealSubject realSubject = new RealSubject();
this.preProxy();
realSubject.buyIphoneXS();
this.postProxy();
}
private void preProxy() {
System.out.println("排队");
}
private void postProxy() {
System.out.println("邮寄");
}
}
Client
package proxy;
/**
* @Author fitz.bai
* @Date 2018/8/31 14:33
*/
public class Client {
public static void main(String[] args) {
Subject proxy = new Proxy();
proxy.buyIphoneXS();
}
}
优点
1、协调调用者和被调用者,降低系统耦合度
2、客户端通过代理对象访问目标对象,起到了保护目标对象的作用
3、 客户端可以针对抽象主题角色进行编程,增加和更换代理类无须修改源代码,符合开闭原则,系统具有较好的灵活性和可扩展性
缺点
1、在客户端和目标对象之间增加了代理对象,会造成请求的处理速度变慢;
2、实现代理模式需要额外的工作,从而增加了系统实现的复杂度。