设计模式——结构型模式(七)

Proxy(代理模式)

目标

为其他对象提供一种代理,以得以控制这个对象的访问。

结构

结构图

Subject作为Proxy与RealSubject的共用接口保证了能使用RealSubject的接口的地方都可以使用Proxy,并且Proxy中保存着一个能够访问到RealSubject的指针。

协作

时序图

Client类在创建一个Proxy对象的同时,Proxy对象也会创建一个RealSubject实例。当Client发出一个请求之后,Proxy对象会在处理了preRequest之后调用RealSubject的request方法,最后再调用afterRequest方法。

适用情形

  1. 远程代理

    为一个对象在不同的地址空间提供一个局部代理对象,有些地方把这种行为称作“Ambassador”。

  2. 虚代理

    当需要创建一个很大的对象,但是不希望在一开始加载的时候就全部创建的。如同当一个网页中有一个非常大的图片的时候,用户往往希望是网页先打开然后再等待图片的加载。

  3. 保护代理

    控制对原始对象的访问,从而限制用户对于某些对象的访问权限。

  4. 智能指针

    在单纯的指针中加入其他的预处理、后处理方法,以便于实现更加复杂的操作。

参与者

  • Proxy

    保存一个可以直接访问到实体的指针,并且实现一个与RealSubject相同的接口,以保证Proxy可以代替RealSubject被调用,以及其他的预处理或者是后处理方法。

  • Subject

    定义RealSubject与Proxy的共用接口。

  • RealSubject

    定义实体对象。

效果

  1. 随着代理类型、附加间接性有着多种用途(略);

  2. 代理模式可以对用户隐藏一种称为copy-on-write的方法,这样可以延迟一个对某个对象的拷贝操作。因为拷贝一个很大的对象往往是非常开销非常大的,使用这样的方法可以保证只有在对象被用户进行了修改之后才发生拷贝动作;

  3. 如果使用范型的话,Proxy对象将不必要知道具体的实体类的名称等。

代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
interface Food{
void eat();
}
class Rice implements Food{
@Override
public void eat() {
System.out.println("Yummy!");
}
}
class CookedRice implements Food{
private Rice rice;
@Override
public void eat() {
System.out.println("Cook!");
rice.eat();
}
}
public class People{
public static void main(String args[]) {
Food rice = new CookedRice();
rice.eat();
}
}

Powered by Hexo and Hexo-theme-hiker

Copyright © 2013 - 2018 Alex's Blog All Rights Reserved.

Yifeng Tang hält Urheberrechtsansprüche.