代理模式

代理模式

代理模式是一种常见的结构型设计模式,当客户端无法直接访问某一个对象或者访问某个对象存在困难时可以通过一个代理对象来间接进行访问。在软件开发中,代理模式又可以分为多种类型,例如保护代理、远程代理、虚拟代理、缓冲代理等,它们应用于不同的场景,满足用户的不同需求。

相信作为程序员,对于google或者Stack Overflow这两个网站应该很熟悉吧,除非你只用百度。但是因为众所周知的原因,我们并不能正常的访问这两个网站。但是群众的智慧是无穷的,我们可以使用VPN来访问国外的网站。这里VPN就是一个代理服务器,这个代理服务器是处于香港、日本、美国等墙外地区的服务器,我们将对google的访问请求转接到代理服务器上,通过代理服务器进行访问,然后再通过代理服务器将访问的结果返回给我们的浏览器,这样我们就可以正常的浏览墙外的世界了。

这里就是代理模式的实际应用,那么在软件开发中,我们怎样去使用代理模式呢?

模式结构

代理模式的基础结构比较简单,UML图如下:

ProxyPattern

根据图可知,代理模式包含如下三个角色:

  1. Subject: 为了能让客户端能够一致性的对待真实对象和代理对象,在代理模式中引入的抽象层。
  2. RealSubject: 真实的业务代码类。
  3. Proxy: 代理类,持有一个真实业务类的实例,在进行真实业务操作前后处理额外的操作。

代码实现

根据UML图可以很轻松的构建出代码

1
2
3
4
5
//业务抽象层
public abstract class Subject {

abstract void request();
}
1
2
3
4
5
6
7
//真实业务代码类
public class RealSubject extends Subject {
@Override
void request() {
System.out.println("真实请求方法");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 代理类
public class ProxySubject extends Subject {

private RealSubject realSubject = new RealSubject();

public void preRequest(){
System.out.println("代理类:请求前操作");
}

@Override
void request() {
preRequest();
realSubject.request();
postRequest();
}

public void postRequest(){
System.out.println("代理类:请求后操作");
}
}

客户端测试代码

1
2
3
4
5
6
7
8
public class Client {

public static void main(String[] args){
Subject subject = new ProxySubject();

subject.request();
}
}

测试结果如下

1
2
3
代理类:请求前操作
真实请求方法
代理类:请求后操作

可以看到,通过代理类,我们在执行真实任务代码前后都进行了额外的操作,且对真实任务代码并没有产生影响。

基于场景的分类

代理模式在实际应用中又会针对不同应用场景进行分类,下面列举几个常见的应用场景分类:

虚拟代理(Virtual Proxy)

虚拟代理是一种常见的代理模式,当我们程序运行或初始化时,对于一些占用较多系统资源,或者需要加载较长时间的对象,我们可以给这些对象提供一个虚拟代理。当主进程运行时,用虚拟代理对象代替真实对象,不影响程序运行,同时异步加载真实对象,或者将消耗大量系统资源的操作推迟创建,当真实对象创建完成时,虚拟对象将用户的请求操作转发给真实对象。

在Android开发中,我们经常会在Application类中进行大量的第三方库或别的初始化操作,而Application这个类是APP运行的第一个类,如果Application中进行的操作过多,会明显影响APP的启动速度,用户体验差。这里我们就可以使用虚拟代理技术,来优化APP的加载过程。

远程代理(Remote Proxy)

远程代理模式也是一种很常见的代理模式,这个模式很像 C/S模式,当我们需要进行很大量的计算或者进行耗费大量的资源操作的时候,可能本地客户端处理性能不佳,而远程主机拥有更好的性能,这时我们可以创建一个远程代理对象,将客户端操作通过网络转发给远程主机进行操作,同时将远程主机的处理结果返回给客户端,对于客户端完全可以认为被代理的对象是本地处理而不是远程,而不必关心实际的处理过程。

通过远程主机的处理,远程代理可以提高系统的整体运行效率。

保护代理(Access Proxy)

保护代理模式可以控制一个对象的访问,可以针对不同身份的访问者提供不同级别的访问权限,拒绝未认证的访问者,这样可以很好的保护数据的安全性,同时也减少了一些不必要的操作,提升了系统运行效率。

缓存代理(Cache Proxy)

缓存代理模式为某一个操作的结果提供一个缓存的存储空间,方便后续操作中共享这些结果,避免某些方法的重复执行,优化系统处理性能。

其实对于数据的缓存优化,在Android开发中我们经常会遇到,我们会利用缓存来存放一些频繁使用的对象,提升系统加载流畅度,避免大量的原始数据操作。这里的缓存代理更像是将对象的缓存操作放到一个缓存代理类中进行操作,不影响原始代码逻辑进行优化。

智能引用代理(Smart Reference Proxy)

智能引用代理与前面的实例类似,通过智能引用代理,我们可以给引用对象一些额外的操作,且不影响正常处理逻辑,例如统计引用次数,日志保存等。

小结

代理模式的基本思想很简单,更多是针对不同的应用场景使用不同的代理模式,更多的时候可能需要多个代理模式组合使用,通过这些灵活的组合操作,我们可以在不影响原代码逻辑的前提下对系统进行优化或者增加功能等。代理模式在实际开发中是一个有效且常用的设计模式。

坚持原创技术分享,您的支持将鼓励我继续创作!