0%

设计模式-代理模式

前言

设计模式将会用 Java 来演示。
这里仅仅是个比较浅层的理解,用于快速回顾,相当于笔记。
之所以记录下代理模式,主要是因为此模式与我所探究的 java 委托 做比较

简介

代理模式是给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。
一个类代表另一个类的功能。
属于结构型模式。

理解

其实就是一个类去代替另一个的功能,同时还能对功能进行扩展。

代理类实现和被代理类同样的接口,在代理类中的代理方法调用被代理类的方法,这样就是实现了代理。当然可以在此基础上对被代理类进行扩展。

应用场景

一般来说是当某个对象不便于直接被访问时,就可以使用代理模式。例如主进程调用此对象代价太大,则由进程外的访问层来代替此对象的功能。

按照职责来分:(具体还不清楚)

  1. 远程代理。
  2. 虚拟代理。
  3. Copy-on-Write 代理。
  4. 保护(Protect or Access)代理。
  5. Cache代理。
  6. 防火墙(Firewall)代理。
  7. 同步化(Synchronization)代理。
  8. 智能引用(Smart Reference)代理。

实现

一个简单的图片加载示例

UML

1

  • ProxyPatternDemo 提供主函数
  • Image 接口提供图像的行为 display()
  • RealImage 类作为 Image 的子类,是真正的图像类
  • ProxyImage 类也继承 Image 类,作用是代理 RealImage 的方法。其中RealImage 作为 ProxyImage 的成员变量

代码

代码示例来自菜鸟教程——代理模式

  1. 图像接口
1
2
3
public interface Image {
void display();
}
  1. 实体类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class RealImage implements Image {

private String fileName;

public RealImage(String fileName){
this.fileName = fileName;
loadFromDisk(fileName);
}

@Override
public void display() {
System.out.println("Displaying " + fileName);
}

private void loadFromDisk(String fileName){
System.out.println("Loading " + fileName);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class ProxyImage implements Image{

private RealImage realImage;
private String fileName;

public ProxyImage(String fileName){
this.fileName = fileName;
}

@Override
// 代理了 realimage 的display方法
public void display() {
if(realImage == null){
realImage = new RealImage(fileName);
}
realImage.display();
}
}
  1. 主函数类
1
2
3
4
5
6
7
8
9
10
11
12
public class ProxyPatternDemo {

public static void main(String[] args) {
Image image = new ProxyImage("test_10mb.jpg");

// 图像将从磁盘加载
image.display();
System.out.println("");
// 图像不需要从磁盘加载
image.display();
}
}
  1. 运行结果
1
2
3
4
Loading test_10mb.jpg
Displaying test_10mb.jpg

Displaying test_10mb.jpg

优点/缺点

优点

  1. 职责清晰
  2. 高扩展性
  3. 智能化

缺点

  1. 由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢
  2. 实现代理模式需要额外的工作,有些代理模式的实现非常复杂。

注意

  1. 和适配器模式的区别:适配器模式主要改变所考虑对象的接口,而代理模式不能改变所代理类的接口。
  2. 和装饰器模式的区别:装饰器模式为了增强功能,而代理模式是为了加以控制。

    参考

    [菜鸟教程——代理模式]