프록시 패턴은 이름에서 알 수 있듯이 대리인 역활을 한다.
대리인이라고 하지만 본 객체의 역활을 모두 수행하는 것은 아니다. 프록시는 본질적 작업을 본 객체에게 위임을 하여 수행한다.
이를 통해서 본 객체의 본질적 작업을 수행하기 전과 후에 작업을 추가할 수 있다. 또한 본질적 작업이 무겁다면 그 작업이 필요로 할 때 초기화를 수행할 수 있다.
Proxy의 종류로는
Virtual Proxy : 인스턴스가 필요한 시점에 생성과 초기화를 실행함
Remote Proxy : 네트워크 상대 쪽에 있음에도 불구 자신의 메소드인 것 처럼 사용, Java의 RMI
Access Proxy : 액세스 제한을 설정한 것 정해진 사용자이면 메소드 호출을 허가. 일반적 구조
예제 소스(출처 : Java 언어로 배우는 디자인 패턴 입문. 영진닷컴)
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
public class ProxyPattern {
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");
}
}
class Printer implements Printable {
private String name;
public Printer() {
heavyJob("Printer의 인스턴스를 생성 중");
}
public Printer(String name) {
this.name = name;
heavyJob("Printer의 인스턴스 (" + name + ")을 생성 중");
}
public void setPrinterName(String name) {
this.name = name;
}
public String getPrinterName() {
return name;
}
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("완료.");
}
}
interface Printable {
public void setPrinterName(String name);
public String getPrinterName();
public void print(String string);
}
class PrinterProxy implements Printable {
private String name;
private Printer real;
public PrinterProxy() {
}
public PrinterProxy(String name) {
this.name = name;
}
public synchronized void setPrinterName(String name) {
if (real != null) {
real.setPrinterName(name);
}
this.name = name;
}
public String getPrinterName() {
return name;
}
public void print(String string) {
realize();
real.print(string);
}
private synchronized void realize() {
if (real == null) {
real = new Printer(name);
}
}
}