Proxy pattern
** 출처
* Printable interface, Printer class, PrinterProxy class
* => [java 언어로 배우는 디자인패턴 입문 / yuki hiroshi / 영진닷컴]에서 발췌한 것에 주석을 단 것입니다.
*/
목차
- proxy pattern class diagram
- ProxyPatternTest (test code)
- Printable interface
- Printer class
- PrinterProxy class
===============================================================================
proxy pattern class diagram
===============================================================================
===============================================================================
ProxyPatternTest
===============================================================================
package com.hdju.patterns;
import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.CoreMatchers.*;
import org.junit.Before;
import org.junit.Test;
import org.junit.Test;
public class ProxyPatternTest {
private String printer1;
private String printer2;
private String printer3;
private String message;
private String printer2;
private String printer3;
private String message;
@Before
public void setUp() throws Exception {
printer1 = "first printer";
printer2 = "second printer";
printer3 = "third printer";
message = "printer test";
}
public void setUp() throws Exception {
printer1 = "first printer";
printer2 = "second printer";
printer3 = "third printer";
message = "printer test";
}
/*
* 아래 예제는 virtual proxy 임.
*/
@Test
public void printProxyTest() {
* 아래 예제는 virtual proxy 임.
*/
@Test
public void printProxyTest() {
Printable printer = new PrinterProxy();
printer.setPrinterName(printer1);
assertThat("=== " + printer1 + " ===" + printer1 + " | printer test",
is(printer.print(message)));
assertThat("=== " + printer1 + " ===" + printer1 + " | printer test",
is(printer.print(message)));
/*
* 프린터 네임을 set해도 프린터 이름이 변경되지 않음을 보여준것은
* 객체를 새로 생성한 것이 아닌것을 보여주기 위한 의도된 것임.
* Printer클래스의 print() 메소드 참조할 것.
*/
printer.setPrinterName(printer2);
assertThat("=== " + printer1 + " ===" + printer1 + " | printer test",
is(printer.print(message)));
* 프린터 네임을 set해도 프린터 이름이 변경되지 않음을 보여준것은
* 객체를 새로 생성한 것이 아닌것을 보여주기 위한 의도된 것임.
* Printer클래스의 print() 메소드 참조할 것.
*/
printer.setPrinterName(printer2);
assertThat("=== " + printer1 + " ===" + printer1 + " | printer test",
is(printer.print(message)));
printer.setPrinterName(printer3);
assertThat("=== " + printer1 + " ===" + printer1 + " | printer test",
is(printer.print(message)));
assertThat("=== " + printer1 + " ===" + printer1 + " | printer test",
is(printer.print(message)));
// 총 수행시간 5s
}
}
@Test
public void printNoneProxyTest() {
public void printNoneProxyTest() {
// Printer 클래스를 직접 이용할 경우 항상 새로 객체를 생성하므로 테스트 코드를 변경함
Printable first = new Printer();
first.setPrinterName(printer1);
assertThat("=== " + printer1 + " ===" + printer1 + " | printer test",
is(first.print(message)));
first.setPrinterName(printer1);
assertThat("=== " + printer1 + " ===" + printer1 + " | printer test",
is(first.print(message)));
Printable second = new Printer();
second.setPrinterName(printer2);
assertThat("=== " + printer2 + " ===" + printer2 + " | printer test",
is(second.print(message)));
second.setPrinterName(printer2);
assertThat("=== " + printer2 + " ===" + printer2 + " | printer test",
is(second.print(message)));
Printable third = new Printer();
third.setPrinterName(printer3);
assertThat("=== " + printer3 + " ===" + printer3 + " | printer test",
is(third.print(message)));
third.setPrinterName(printer3);
assertThat("=== " + printer3 + " ===" + printer3 + " | printer test",
is(third.print(message)));
// 총 수행시간 15s
}
}
/**
* Proxy 패턴은 초기 로딩이 많이 걸리는 경우 사용하면 속도 개선이 있다.
*/
}
* Proxy 패턴은 초기 로딩이 많이 걸리는 경우 사용하면 속도 개선이 있다.
*/
}
===============================================================================
Printable interface
===============================================================================
package com.hdju.patterns;
public interface Printable {
public void setPrinterName(String printerName);
public void setPrinterName(String printerName);
public String getPrinterName();
public String print(String message);
}
}
===============================================================================
Printer class
===============================================================================
package com.hdju.patterns;
public class Printer implements Printable {
private String name;
public Printer() {
heavyJob("Printer 인스턴스를 생성 중");
}
heavyJob("Printer 인스턴스를 생성 중");
}
public Printer(String name) {
this.name = name;
heavyJob("Printer의 인스턴스 (" + name + ") 을 생성 중");
}
this.name = name;
heavyJob("Printer의 인스턴스 (" + name + ") 을 생성 중");
}
@Override
public void setPrinterName(String printerName) {
this.name = printerName;
}
public void setPrinterName(String printerName) {
this.name = printerName;
}
@Override
public String getPrinterName() {
return this.name;
}
public String getPrinterName() {
return this.name;
}
@Override
public String print(String message) {
String printResult = "=== " + name + " ===" + name;
return printResult + " | " + message;
}
public String print(String message) {
String printResult = "=== " + name + " ===" + name;
return printResult + " | " + message;
}
private void heavyJob(String jobSubject) {
System.out.println(jobSubject);
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println(jobSubject);
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
System.out.print(".");
}
System.out.println("완료.");
}
}
System.out.print(".");
}
System.out.println("완료.");
}
}
===============================================================================
PrinterProxy class
===============================================================================
package com.hdju.patterns;
public class PrinterProxy implements Printable {
private String name;
private Printer real;
private String classname;
private Printer real;
private String classname;
public PrinterProxy() {
}
public PrinterProxy(String name) {
this.name = name;
}
this.name = name;
}
public PrinterProxy(String name, String classname) {
this.name = name;
this.classname = name;
}
this.name = name;
this.classname = name;
}
@Override
public void setPrinterName(String printerName) {
this.name = printerName;
}
public void setPrinterName(String printerName) {
this.name = printerName;
}
@Override
public String getPrinterName() {
return this.name;
}
public String getPrinterName() {
return this.name;
}
@Override
public String print(String message) {
realize();
return real.print(message);
}
public String print(String message) {
realize();
return real.print(message);
}
/*
* synchronized를 사용하지 않을 경우 스레드 세이프하지 않다.
*/
private synchronized void realize() {
if (real == null) {
real = new Printer(name);
/*
* REFACTORING point : Printer 클래스가 소스에 직접 지정되어있다. 이를 해결하기 위해
* classname을 별도로 입력받아 사용하도록 하면 커플링을 줄일수 있다.
*
* real = (Printable)Class.forName(classname).newInstance();
* real.setPrinterName(name);
*
* (예외처리 생략)
*/
}
}
* synchronized를 사용하지 않을 경우 스레드 세이프하지 않다.
*/
private synchronized void realize() {
if (real == null) {
real = new Printer(name);
/*
* REFACTORING point : Printer 클래스가 소스에 직접 지정되어있다. 이를 해결하기 위해
* classname을 별도로 입력받아 사용하도록 하면 커플링을 줄일수 있다.
*
* real = (Printable)Class.forName(classname).newInstance();
* real.setPrinterName(name);
*
* (예외처리 생략)
*/
}
}
}
===============================================================================
===============================================================================
댓글
댓글 쓰기