1、定义
当我们不想对象被直接访问时,为某个对象提供一种代理来控制这个对象的访问,比如系统某些命令,我们不希望用户直接执行,而是提供一种代理,由代理对象来执行,以确保系统安全,这种模式被称为代理模式。代理模式属于结构型模式。
2、优缺点
2.1、优点
- 职责清晰
- 高扩展性
- 智能化
2.2、缺点
- 由于中间增加了代理对象,逻辑处理、请求响应可能耗时增加。
- 实现代理模式可能需要额外的工作,增加系统复杂度。
3、使用场景
- 远程代理
- 虚拟代理
- 保护代理
- 缓存代理
- 。。。。
4、注意事项
- 和适配器模式的区别:适配器模式主要改变所考虑对象的接口,而代理模式不能改变所代理类的接口。
- 和装饰器模式的区别:装饰器模式为了增强功能,而代理模式是为了加以控制。
5、实现
我们将创建一个 Image 接口和实现了 Image 接口的实体类。ProxyImage 是一个代理类,减少 RealImage 对象加载的内存占用。ProxyPatternDemo,我们的演示类使用 ProxyImage 来获取要加载的 Image 对象,并按照需求进行显示。
5.1、创建Image接口
/**
* desc: image接口
*
* @author xuebin
* @version 1.0
* @date 2020/06/11 14:39
*/
public interface Image {
// 显示图片
public void display();
}
5.2、创建接口的实现类,加载并显示图片的类。
/**
* desc:
*
* @author xuebin
* @version 1.0
* @date 2020/06/11 14:41
*/
public class RealImage implements Image {
private String fileName;
public RealImage(String fileName){
this.fileName = fileName;
loadImageFromDisk(fileName);
}
/**
* 从磁盘上加载图片
*/
public void loadImageFromDisk(String fileName){
System.out.println("从磁盘加载图片,fileName:"+fileName);
}
@Override
public void display() {
System.out.println("展示图片");
}
}
5.3、创建加载、显示图片代理类
/**
* desc:
*
* @author xuebin
* @version 1.0
* @date 2020/06/11 14:43
*/
public class ProxyRealImage implements Image {
private RealImage realImage;
private String fileName;
public ProxyRealImage(String fileName) {
this.fileName = fileName;
}
@Override
public void display() {
if (realImage == null){
realImage = new RealImage(fileName);
}
realImage.display();
}
}
5.4、测试样例
/**
* desc:
*
* @author xuebin
* @version 1.0
* @date 2020/06/11 14:46
*/
public class ProxyImageTest {
public static void main(String[] args) {
// 测试代理模式
Image image = new ProxyRealImage("好图片.jpg");
image.display();
System.out.println("===============");
image.display();
}
}
5.5、测试结果
从磁盘加载图片,fileName:好图片.jpg
展示图片
===============
展示图片
。。。: 可以看出,从磁盘只加载一次,节省IO