小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
本文已参与「掘力星计划」,赢取创作大礼包,挑战创作激励金。
概述
又叫委托模式,结构型设计模式,能够提供对象的替代品,控制着对于原对象的访问,是一个使用率非常高的模式。
角色
抽象主题:申明了服务的接口,代理类必须遵循该接口。
服务主题:服务类,是被代理的一方,提供了实际业务逻辑的服务接口。
代理主题:代理类,包含了一个指向服务对象的引用成员变量,负责在需要的时候创建或删除服务对象,代理完成其任务,通常情况下会在服务类前后做预处理和善后处理工作。
模板
抽象接口:申明了代理类跟服务类必须实现的功能。
public interface IGamePlayer {
/**
* 杀怪
*/
public void killBoss();
/**
* 通关
*/
public void clearance();
}
服务类:实际的服务处理逻辑
public class GamePlayer implements IGamePlayer{
private String name;
public GamePlayer(String name) {
this.name = name;
}
@Override
public void killBoss() {
System.out.println(this.name + "三打白骨精!");
}
@Override
public void clearance() {
System.out.println(this.name + "打死了白骨精!");
}
}
代理类:对服务类进行代理
public class GamePlayerProxy implements IGamePlayer{
private IGamePlayer player;
public GamePlayerProxy(IGamePlayer player) {
this.player = player;
}
/**
* 记录打怪的时间
*/
private void log(){
System.out.println("打怪时间:" + new Date().toString());
}
/**
* 代理方法
*/
@Override
public void killBoss() {
this.log();
player.killBoss();
}
/**
* 代理方法
*/
@Override
public void clearance() {
player.clearance();
this.count();
}
/**
* 计算升级所用的时间
*/
private void count(){
System.out.println("打死白骨精耗费了三天时间");
}
}
客户端:客户端的使用案例
public class ProxyPattern {
public static void main(String[] args) {
// 服务类实例
IGamePlayer player = new GamePlayer("孙悟空");
// 代理类实例
IGamePlayer proxy = new GamePlayerProxy(player);
// 方法调用
proxy.killBoss();
proxy.clearance();
}
}
小结
优点
开闭原则:可以在不对服务端或客户端做出修改的情况下创建新的代理
高扩展性:可以在客户端毫无察觉的情况下控制服务对象,只要服务类实现了接口,代理类就完全可以在不做任何修改的情况下代理各种代理类。
智能化:代理类可以在运行时才缺点需要去代理的服务类。
缺点
代码可能会变得复杂,因为需要新建许多类,同时服务响应也有可能会延迟。
适用场景
- 远程代理:为一个位于不同地址空间的对象提供一个局部代理对象
- 虚拟代理:创建一些耗费较多资源的对象时,可以先创建代理对象,将真实对象的创建延迟
- 保护代理:控制对一个对象的访问,可以给不同的用户提供不同的使用权限
- 缓存代理:为某一个目标操作的结果提供临时的存储空间,以便于多个客户端共享
- 同步代理:几个用户使用一个对象而不冲突
- 智能引用:提供一些额外的操作,例如访问记录的流量和次数等