일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- Singleton
- Design Pattern
- 공부
- Java
- 인프런
- 카카오톡1차
- study
- math
- 인강리뷰
- 알고리즘
- 프로그래머스
- 독서
- 우아한테크코스
- JPA
- javascript
- 후기
- 람다
- 회고
- 디자인패턴
- spring
- 자바
- 인코딩
- 독서리뷰
- 에러
- Eclipse
- 이펙티브자바
- 매핑
- Head First Design Pattern
- Oracle
- 오라클
- Today
- Total
Lee's Grow up
[디자인패턴/Design Pattern] Proxy Pattern / 프록시 패턴 본문
관련 내용은 [자바 언어로 배우는 디자인 패턴 입문]
,[Head First Design Pattern]
의 내용을 참고해서 정리한 내용입니다.
잘못된 부분은 댓글로 피드백 부탁드립니다.
1. Proxy 패턴이란?
어떤 객체에 대한 접근을 제어하기 위한 용도로 대리인이나 대변인에 해당하는 객체를 제공하는 패턴
2. Proxy 패턴의 등장인물
- Subject(주체)의 역할
- Proxy 역할과 RealSubject 역할을 동일시하기 위한 인터페이스(API)를 결정합니다. 이 덕분에 클라이언트는 둘의 역할 차이를 몰라도 됩니다.
- Proxy(대리인)의 역할
- Client의 요구를 할 수 있을 만큼 처리하고, 필요할 경우 RealSubject에게 처리를 맡깁니다.
- RealSubject(실제의 주체)의 역할
- Proxy에서 요청이 들어왔을때 요청에 대한 응답을 합니다.
- Proxy에서 요청이 들어왔을때 요청에 대한 응답을 합니다.
3. 예제
3-1. 예제 클래스 다이어그램
3-2. PritableSubject 인터페이스
public interface PrintableSubject {
void setPrinterName(String name);
String getPrinterName();
void print(String string);
}
역할 설명에서 언급했던것처럼 Proxy
와 RealSubject
역할의 인터페이스(API)를 정의해줍니다.
3-3. PrinterRealSubject 클래스
public class PrinterRealSubject implements PrintableSubject {
private String name;
public PrinterRealSubject(String name) {
this.name = name;
heavyJob("PrinterRealSubject[" + name + "] 인스턴스 생성중..");
}
private void heavyJob(String string) {
// TODO Auto-generated method stub
System.out.println(string);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("생성 완료...");
}
public void setPrinterName(String name) {
this.name = name;
}
public String getPrinterName() {
return name;
}
public void print(String string) {
System.out.println(string);
}
}
인터페이스를 구현하기 위해 setPrinterName()
, getPrinterName()
, print()
를 재정의해주고, 객체의 인스턴스 생성의 비용을 무겁게 하기 위해 heavyJob()
이란 메소드를 통해 3초를 지연시킵니다.
3-4. PrinterProxy 클래스
public class PrinterProxy implements PrintableSubject {
private String name;
private PrinterRealSubject 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 synchronized void print(String string) {
realize();
real.print(string);
}
private synchronized void realize() {
if (real == null) {
real = new PrinterRealSubject(name);
}
}
}
대리인으로써 처리가 가능한 부분은 객체가 맡아서 처리를 해줍니다. ex ) getPrinterName()
그리고 실제 RealJubject가 필요한 시점에 해당 객체에게 요청을 위임합니다.
3-5. Main 클래스
public class Main {
public static void main(String[] args) {
PrintableSubject p = new PrinterProxy("Simple");
// 프록시가 실행 됨
System.out.println(p.getPrinterName());
// realSubject가 실행
p.print("프린트 요청");
}
}
실행 결과
Simple
PrinterRealSubject[Simple] 인스턴스 생성중..
생성 완료...
프린트 요청
왜 사용할까 ?
시작하기에 앞서 Proxy Pattern의 정의를 아래와 같이 설명했습니다.
- 어떤 객체에 대한 접근을 제어하기 위한 용도로 대리인이나 대변인에 해당하는 객체를 제공하는 패턴
그런데 예제만 보고는 왜? 라는 생각이 드실 수 있습니다.
- 로직에 많은 비용이 필요하면 처음부터
Printer
클래스에서 분리해서 사용하면 되는거 아니야?
라는 의문에는 디자인의 원칙에 의해서 객체들의 역할을 분리해서 개별적으로 수정이 가능하게 하기 위함입니다. 즉 유지보수가 용이하고 클라이언트 입장에서는 지연이 필요할경우 Proxy
객체를 사용 필요없이 사용할 경우 PrinterRealSubject
를 사용할 수 있습니다.
마지막으로 Proxy Pattern
의 정의를 비용이 많이 필요한 경우 역할을 나눠서 지연시킬 수 있는 패턴이라고 정의하지 않고, 본문처럼 포괄적으로 설명한 이유는 무엇일까? Proxy Pattern
은 여러 종류 존재하기 때문에 포괄적인 의미만 전달했습니다.
Proxy Pattern의 종류
- Virtual Proxy(가상 프록시) : 예제에 해당하는 프록시이며, 인스턴스가 필요한 시점에 생성, 초기화를 실행합니다.
- Remote Proxy(원격 프록시 ) : 네트워크가 연결된 상황에서 원격으로 로컬 객체를 원격 객체처럼 사용할 수 있게 해줍니다. Java RMI 등을 사용
- Access Proxy(보호 프록시) : RealSubject 기능에 대해서 엑세스 제한을 설정합니다.
- Caching Proxy(캐싱 프록시) : 지연이 많이 드는 작업을 임시로 저장, 여러 클라이언트에게 공유합니다.
- 기타 : 방화벽 프록시, 스마트 레퍼런스 프록시, 동기화 프록시, 복잡도 숨김 프록시, 지연 복사 프록시 등.
4. 관련 패턴
Adapter
패턴 : 연결 해준다는 관점은 같지만 Adapter는 서로 다른 인터페이스를 연결해줍니다. linkDecorator
패턴 : 구현은 비슷하지만 목적이 다릅니다. 새로운 기능을 추가할 때 사용합니다. link
5. 비교하기
객체를 감싸는 패턴이 많은데 구분을 하기 위해 차이점을 정리했습니다,
'PROGRAMMING > 디자인패턴' 카테고리의 다른 글
[디자인패턴/Design Pattern] Builder 패턴 / 빌더 패턴 (0) | 2019.12.30 |
---|---|
[디자인패턴/Design Pattern] Bridge Pattern / 브리지 패턴 (0) | 2019.12.26 |
[디자인패턴/Design Pattern] State Pattern / 스태이트 패턴 (0) | 2019.12.17 |
[디자인패턴/Design Pattern] Composite Pattern / 컴포지트 패턴 (0) | 2019.12.17 |
[디자인패턴/Design Pattern] Facade Pattern / 퍼사드 패턴 (0) | 2019.12.16 |