βοΈ Java Design-Pattern 22 - Proxy
βοΈ Java Design-Pattern 22 - Proxy
π
γJAVA μΈμ΄λ‘ λ°°μ°λ λμμΈ ν¨ν΄ : μ½κ² λ°°μ°λ GoFμ 23κ°μ§ λμμΈ ν¨ν΄γλ₯Ό μ½κ³ μ 리ν κΈμ λλ€.
Proxy ν¨ν΄μ΄λ?
Proxyλ λ리μΈμ΄λΌλ λ»μΌλ‘, μΌμ ν΄μΌ ν λ³ΈμΈμ λμ νλ μ¬λμ΄λ€.- κ°μ²΄μ§ν₯ νλ‘κ·Έλ¨μμλ λ³ΈμΈλ, λ리μΈλ κ°μ²΄κ° λλ€.
- λ°λΉ μ κ·Έ μΌμ ν μ μλ λ³ΈμΈ κ°μ²΄λ₯Ό λμ ν΄μ λλ¦¬μΈ κ°μ²΄κ° μ΄λ μ λ μΌμ μ²λ¦¬νλ€.
μμ νλ‘κ·Έλ¨
- μ΄λ² μμ νλ‘κ·Έλ¨μ βμ΄λ¦ λΆμΈ νλ¦°ν°βμ΄λ€.
Mainν΄λμ€λPrinterProxyμΈμ€ν΄μ€λ₯Ό μμ±νμ¬ μ΄λ¦μ λΆμ΄κ³ κ·Έ μ΄λ¦μ νμνλ€.- μ΄λ¦ μ€μ μ΄λ μ·¨λμ λν΄μλ μ§μ§
PrinterμΈμ€ν΄μ€λ μμ±λμ§ μμλ€. - μ€μ λ‘ νλ¦°ν°νλ λ¨κ³κ° λμ΄μμΌ
PrinterProxyν΄λμ€λPrinterμΈμ€ν΄μ€λ₯Ό μμ±νλ€. Printerν΄λμ€μPrinterProxyν΄λμ€λ₯Ό λμΌμνκΈ° μν΄Printableμ΄λΌλ μΈν°νμ΄μ€λ₯Ό μ μνλ€.- μ¬κΈ°μλ
PrinterμΈμ€ν΄μ€ μμ±μ μ€λ μκ°μ΄ κ±Έλ¦°λ€λ μ μ λ‘ νλ‘κ·Έλ¨μ μμ±νλ€. - λ¬Όλ‘ μμ νλ‘κ·Έλ¨μΌ λΏμ΄λ―λ‘ 5μ΄ μ λμ μκ°μ λ² λΏμ΄λ€.
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
44
45
46
47
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("μλ£");
}
}
- μμ λ§ν κ²μ²λΌ κ°μ§ λ¬΄κ±°μ΄ μμ
μΈ
heavyJob()λ©μλλ₯Ό κ°κ³ μλ€. Proxyν¨ν΄μ ν΅μ¬μPrinterν΄λμ€κ° μλPrinterProxyν΄λμ€μ μλ€.
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);
}
Printerν΄λμ€μPrinterProxyν΄λμ€λ λμΌμνκΈ° μν κ²μ΄λ€.- κ°κ° μ΄λ¦ μ€μ , μ΄λ¦ μ·¨λ, νλ¦°νΈ μμμ μν λ©μλμ΄λ€.
PrinterProxy ν΄λμ€
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
public class PrinterProxy implements Printable {
private String name; // μ΄λ¦
private Printer real; // λ³ΈμΈ
/* μμ±μ */
public PrinterProxy() {
this.name = "No Name";
this.real = null;
}
/* μμ±μ(μ΄λ¦ μ§μ ) */
public PrinterProxy(String name) {
this.name = name;
this.real = null;
}
/* μ΄λ¦ μ€μ */
@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);
}
}
}
Printerν΄λμ€μ λλ¦¬μΈ μν μ νλ©°,PrintableμΈν°νμ΄μ€λ₯Ό ꡬννλ€.nameνλλ μ΄λ¦μ μ μ₯νκ³realνλλ λ³ΈμΈμ μ μ₯νλ€.setPrinterName()λ©μλλ μλ‘ μ΄λ¦μ μ€μ νλ€.realμ΄nullμ΄λ©΄ λ¨μν μ΄λ¦μ μ€μ νκ³ , μλλΌλ©΄ λ³ΈμΈμ λν΄μλ κ·Έ μ΄λ¦μ μ€μ νλ€.getPrinterName()λ©μλλ μμ μnameνλ κ°μ λ°ννλ€.print()λ©μλλ λ리μΈμ΄ ν μ μλ λ²μλ₯Ό λμ΄μλ μ²λ¦¬μ΄κΈ° λλ¬Έμ,realize()λ©μλλ₯Ό νΈμΆνμ¬ λ³ΈμΈμ μμ±νλ€.realνλμλ λ³ΈμΈμ΄ μ μ₯λμ΄ μκΈ° λλ¬Έμreal.print()λ©μλλ₯Ό νΈμΆνλ€.- μ΄λ₯Ό μμμ΄λΌκ³ νλ€.
setPrinterName(),getPrintName()λ©μλλ₯Ό μ¬λ¬ λ² νΈμΆν΄λPrinterμΈμ€ν΄μ€λ μμ±λμ§ μκ³ ,PrinterμΈμ€ν΄μ€ λ³ΈμΈμ΄ μ λ§λ‘ νμν λ μμ±λλ€.realize()λ©μλλ λ¨μνrealνλκ°nullμ΄λ©΄newν€μλλ₯Ό ν΅ν΄ μμ±νκ³ , μλλΌλ©΄ μ무 μΌλ νμ§ μλλ€.- κΈ°μ΅ν΄λμ΄μΌ νλ κ²μ
Printerν΄λμ€λPrinterProxyμ μ‘΄μ¬λ₯Ό λͺ¨λ₯Έλ€λ μ μ΄λ€. - μμ μ΄
PrinterProxyλ₯Ό κ²½μ ν΄μ νΈμΆλλμ§, μ§μ νΈμΆλλμ§Printerν΄λμ€λ λͺ¨λ₯Έλ€. - λ°λ©΄
PrinterProxyν΄λμ€λPrinterν΄λμ€λ₯Ό μκ³ μλ€. - μ¦
PrinterProxyν΄λμ€λPrinterν΄λμ€μ κ³ μ μ μΌλ‘ κ²°ν©λ λΆνμΈ κ²μ΄λ€. - λν λ©ν° μ°λ λ νκ²½μ κ³ λ €ν΄
setPrinterName(),realize()λ©μλλsynchronizedλ‘ μ μΈλμ΄ μλ€.
Main ν΄λμ€
1
2
3
4
5
6
7
8
9
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.");
}
}
PrinterProxyν΄λμ€λ₯Ό κ²½μ ν΄μPrinterν΄λμ€λ₯Ό μ΄μ©νλ ν΄λμ€μ΄λ€.PrinterμΈμ€ν΄μ€λprint()λ©μλλ₯Ό νΈμΆν νμ μμ±λλ€.
Proxy ν¨ν΄μ λ±μ₯μΈλ¬Ό
Printable μΈν°νμ΄μ€
ProxyμRealSubjectλ₯Ό λμΌμνκΈ° μν μΈν°νμ΄μ€λ₯Ό μ μνλ λ³ΈμΈ(Subject) μμ λ§‘μλ€.ClientλProxyμRealSubjectλ₯Ό ꡬλ³ν νμκ° μλ€.
PrinterProxy ν΄λμ€
Clientμ μμ²μ μ΅λν μ²λ¦¬νκ³ , μ λ§λ‘RealSubjectκ° νμν λRealSubjectλ₯Ό μμ±νλ λ리μΈ(Proxy) μμ λ§‘μλ€.Subjectμ μ μλ μΈν°νμ΄μ€λ₯Ό ꡬννλ€.
Printer ν΄λμ€
Proxyλ§μΌλ‘ κ°λΉν μ μμ λ μμ±λλ μ€μ λ³ΈμΈ(RealSubject) μμ λ§‘μλ€.- μ΄ μν λ
Subjectμ μ μλ μΈν°νμ΄μ€λ₯Ό ꡬννλ€.
Main ν΄λμ€
Proxyν¨ν΄μ μ΄μ©νλClientμμ λ§‘μλ€.
μ± μμ μ μνλ ννΈ
λ리μΈμ μ¬μ©ν΄ μλ μ¬λ¦¬κΈ°
- μμ νλ‘κ·Έλ¨μμλ
Proxyλ₯Ό μ¬μ©ν¨μΌλ‘μ¨ μ€μ λ‘print()λ©μλλ₯Ό νΈμΆν λκΉμ§ λ¬΄κ±°μ΄ μ²λ¦¬λ₯Ό μ΅λν λ¦μΆ μ μμλ€. - μ΄κΈ°νμ μκ°μ΄ 걸리λ κΈ°λ₯μ΄ λ§μ λκ·λͺ¨ μμ€ν μ μκ°ν΄λ³΄λ©΄ μ λΏμ κ²μ΄λ€.
- κ°λ Ή μμ μμ μ μ΄μ©νμ§ μλ κΈ°λ₯κΉμ§ μ λΆ μ΄κΈ°νν΄λ²λ¦¬λ©΄ μ ν리μΌμ΄μ μμ μκ°μ΄ κΈΈμ΄μ§λ€.
- μ€μ λ‘ κ·Έ κΈ°λ₯μ μ¬μ©νλ λ¨κ³κ° λμμ λ μ΄κΈ°ννλ νΈμ΄ κ·Έ μ¬μ©μμ μ€νΈλ μ€λ₯Ό λμ΄μ€λ€.
λ리μΈκ³Ό λ³ΈμΈμ λλ νμκ° μμκΉ?
PrinterProxyν΄λμ€μPrinterν΄λμ€λ₯Ό λλμ§ μκ³Printerν΄λμ€ μμ μ²μλΆν° μ§μ° νκ° κΈ°λ₯μ λ£μ΄ λ μλ μλ€.- κ·Έλ¬λ λΆλ¦¬λ₯Ό ν΅ν΄ νλ‘κ·Έλ¨μ΄ λΆννλλ©΄ κ°λ³μ μΌλ‘ μμ ν μ μλ€.
PrinterProxyν΄λμ€μ ꡬνμ λ°κΎΈλ©΄PrintableμΈν°νμ΄μ€μ 무μμ λ리μΈμ΄ μ²λ¦¬νκ³ λ¬΄μμ μμν μ§ λ³κ²½ ν μ μλ€.- κ·Έλ° λ³κ²½μ νλλΌλ
Printerν΄λμ€λ μμ ν νμκ° μ ν μλ€. - μ§μ° νκ°λ₯Ό μ ν νμ§ μμΌλ €λ©΄
Mainν΄λμ€μμPrinterProxyν΄λμ€κ° μλPrinterν΄λμ€μ μΈμ€ν΄μ€λ₯Όnewν€μλλ‘ μμ±νλ©΄ λλ€. PrinterProxyν΄λμ€λProxyμμ΄λΌλ κΈ°λ₯μ νννκ³ μκΈ° λλ¬Έμ, κ·Έ κΈ°λ₯μ μ¬μ©ν μ§ μ ν μ§λPrinterProxyλ₯Ό μ¬μ©ν μ§ μ¬μ©νμ§ μμμ§λ‘ κ²°μ λλ€.
λ리μ μμ
- λλ¦¬μΈ νΌμ μ²λ¦¬ν μ μλ μΌμ μ§μ μ²λ¦¬νλ€.
- νμ§λ§ κ·Έλ μ§ μμΌλ©΄ λ³ΈμΈμκ² μμνλ€.
- μλ νμ€ μΈκ³μμλ λ³ΈμΈμ΄ λ리μΈμκ² μ± μμ λ§‘κΈ°λλ°, λμμΈ ν¨ν΄μμλ λ°λλ‘ λμ΄ μλ€.
ν¬κ³Όμ μ΄λ?
PrinterμPrinterProxyλ κ°μPrintableμΈν°νμ΄μ€λ₯Ό ꡬννκΈ° λλ¬Έμ,Mainν΄λμ€μμ νΈμΆνλ κ³³μ΄ μ΄λ€ ν΄λμ€μ΄λ μκ΄νμ§ μλλ€.PrinterProxyλ₯Ό μ€κ°μ λμ΄λ,Printerλ₯Ό μ§μ μ΄μ©ν΄λ λ¬Έμ μμ΄ μ¬μ©ν μ μλ€.- μ΄λ¬ν νΉμ±μ ν¬κ³Όμ μ΄λΌκ³ νλ€.
HTTP νλ‘μ
- νλ‘μλΌκ³ νλ©΄
HTTPνλ‘μλ₯Ό λ μ¬λ¦¬λ μ¬λμ΄ μμ μλ μλ€. HTTPνλ‘μλHTTPμλ²μHTTPν΄λΌμ΄μΈνΈ μ¬μ΄μμ μΉ νμ΄μ§ μΊμ± λ±μ νλ μννΈμ¨μ΄μ΄λ€.- μΊμ± λν
Proxyν¨ν΄μ μ μ©ν΄μ μκ°ν μ μλ€. - μΉ λΈλΌμ°μ κ° μλ μΉ νμ΄μ§λ₯Ό νμν λ μ격μ§μ μλ μΉ μλ²μ μ μν΄μ κ·Έ νμ΄μ§λ₯Ό κ°μ Έμ€λ κ²μ΄ μλλΌ,
HTTPνλ‘μκ° μΊμ±ν΄ λμ νμ΄μ§λ₯Ό λμ κ°μ Έμ¨λ€. - μ΅μ μ λ³΄κ° νμν λλ μΉ νμ΄μ§μ μ ν¨ κΈ°κ°μ΄ μ§λ¬μ λ λΉλ‘μ μΉ μλ²λ‘ μΉ νμ΄μ§λ₯Ό κ°μ§λ¬ κ°λ€.
- μ¬κΈ°μλ μΉ λΈλΌμ°μ κ°
Client,HTTPνλ‘μκ°Proxy, κ·Έλ¦¬κ³ μΉ μλ²κ°RealSubjectμ ν΄λΉνλ€.
λ€μν Proxy
κ°μ νλ‘μ(Virtual Proxy)
- μ΄ μ₯μμ μκ°ν
Proxyν¨ν΄ - μ€μ λ‘ μΈμ€ν΄μ€κ° νμν μμ μμ μμ± λ° μ΄κΈ°ννλ€.
μ격 νλ‘μ(Remote Proxy)
RealSubjectμμ΄ λ€νΈμν¬ μ νΈμ μλλΌλ λ§μΉ λ°λ‘ μμ μλ κ²μ²λΌ λ©μλλ₯Ό νΈμΆν μ μλ€.Java RMIλ±μ΄ μ¬κΈ°μ ν΄λΉλλ€.
λ³΄νΈ νλ‘μ(Access Proxy)
Access ProxyλRealSubjectμμ κΈ°λ₯μ λν΄ μ κ·Ό μ νμ μ€μ νλ€.- μ§μ λ μ¬μ©μλΌλ©΄ λ©μλ νΈμΆμ νκ°νμ§λ§, λλ¨Έμ§λ μ€λ₯κ° λλλ‘ μ²λ¦¬νλ νλ‘μμ΄λ€.
This post is licensed under CC BY 4.0 by the author.


