【图解设计模式】Proxy模式

当不一定需要本人亲自进行工作时,就可以寻找代理人去完成工作。当代理人遇到无法自己解决的事情时就会去找本人解决该问题。

示例

一个带名字的打印机。

类图

mqEOmQ.png

时序图

mqVkm4.png

Printer类

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public class Printer implements Printable {
private String name;

public Printer() {
heavyJob("Printer的实例生成中");
}

public Printer(String name) {
this.name = name;
heavyJob("Printer的实例生成中("+ name + ")");
}

@Override
public void setPrinterName(String name) {
this.name = name;
}

@Override
public String getPrinterName() {
return name;
}

@Override
public void print(String string) {
System.out.println("=== " + name + " ===");
System.out.println(string);
}

private void heavyJob(String msg) {
System.out.print(msg);

for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}

System.out.print(".");
}

System.out.println("结束。");
}
}

Printable接口

1
2
3
4
5
public interface Printable {
public abstract void setPrinterName(String name);
public abstract String getPrinterName();
public abstract void print(String string);
}

PrintableProxy类

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
28
29
30
31
32
public class PrinterProxy implements Printable {
private String name;
private Printer real;

public PrinterProxy(String name) {
this.name = name;
}

@Override
public synchronized void setPrinterName(String name) {
if (real != null)
real.setPrinterName(name);

this.name = name;
}

@Override
public String getPrinterName() {
return name;
}

@Override
public void print(String string) {
realize();
real.print(string);
}

private synchronized void realize() {
if (real == null)
real = new Printer(name);
}
}

Main类

1
2
3
4
5
6
7
8
9
10
public class Main {

public static void main(String[] args) {
Printable p = new PrinterProxy("Alice");
System.out.println("现在的名字是" + p.getPrinterName() + "。");
p.setPrinterName("Bob");
System.out.println("现在的名字是" + p.getPrinterName() + "。");
p.print("Hello, world.");
}
}

运行结果

1
2
3
4
5
现在的名字是Alice。
现在的名字是Bob。
Printer的实例生成中(Bob).....结束。
=== Bob ===
Hello, world.

登场角色

Subject(主体)

Subject角色定义了使Proxy角色和RealSubject角色之间具有一致性的接口。由于存在Subject角色,所以Client角色不必在意它所使用的究竟是Proxy角色还是RealSubject角色。在示例程序中,由Printable接口扮演此角色。

Proxy(代理人)

Proxy角色会尽量处理来自Client角色的请求。只有当自己不能处理时,它才会将工作交给RealSubject角色。Proxy角色只有在必要时才会生成RealSubject角色。Proxy角色实现了在Subject角色中定义的接口(API)。在示例程序中,由PrinterProxy类扮演此角色。

RealSubject(实际的主体)

“本人”RealSubject角色会在“代理人”Proxy角色无法胜任工作时出场。它与Proxy角色一样,也实现了在Subject角色中定义的接口(API)。在示例程序中,由Printer类扮演此角色。

Client(请求者)

使用Proxy模式的角色。在示例程序中,由Main类扮演此角色。

类图

mq8Qjs.png