Java

[Design Pattern] 대리인 패턴(Proxy Pattern)

구루싸 2020. 7. 22. 23:18
반응형
SMALL

이번 학습 주제는

대리인(Proxy) 패턴입니다

Proxy는 주로 HTTP Proxy를

떠올리실 것 같네요

아무튼 대리인 패턴은

매우 바쁜 오브젝트 대신에

일을 처리해 줄 수있는

오브젝트가 있는 패턴입니다

물론 처리할 수 있는

일에는 한계가 존재합니다

그럼 대리인 패턴의

역할들을 정리하고

시작하겠습니다

역할 설명
Subject(주체) Proxy 역할과 RealSubject 역할을 동일시하기 위한 인터페이스를 결정
Proxy(대리인) Client 역할의 요구를 할 수 있는 만큼 처리하고 처리할 수 없어 RealSubject 역할이 필요해지면 그 때 RealSubject 역할을 생성
Real Subject(실제의 주체) Proxy 역할에서 감당할 수 없는 일이 발생했을 때 등장
Client(의뢰인) Proxy 패턴을 이용하는 역할

역할을 살펴보는 것만으로

이해하기는 어렵네요-_-

구현을 해보겠습니다

1. 인터페이스(Interface) Printable.java

package proxyPattern;

public interface Printable {
	public abstract void setPrinterName(String name);
	public abstract String getPrinterName();
	public abstract void print(String string);
}

2. 클래스(Class) Printer.java

package proxyPattern;

public 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.println(msg);
		for ( int i = 0; i < 5; i++ ) {
			try {
				Thread.sleep(1000);
			} catch(InterruptedException e) {
			}
			System.out.print(".");
		}
		System.out.println("완료.");
	}
}

3. 클래스(Class) PrinterProxy.java

package proxyPattern;

public 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);
		}
	}
}

4. 클래스(Class) Test.java

import proxyPattern.*;
public class Test {
	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("Welcome!!");
	}
}

위의 코드에서

PrinterProxy 클래스와 

Printer 클래스는 같은

Printable 인터페이스를

구현하고 있습니다

Test 클래스는

실제로 호출하는 곳이

PrinterProxy 클래스이든

Printer 클래스이든

상관하지 않는데

이럴 때 PrinterProxy 클래스는

투과적이라고 말합니다

Proxy 패턴에는

다양한 종류가 있습니다

살펴보면 아래와 같습니다

종류 설명
Virtual Proxy(가상 프록시) 인스턴스가 필요한 시점에 생성 및 초기화를 실행
Remote Proxy(원격 프록시) Real Subject 역할이 네트워크의 상대 쪽에 있음에도 불구하고 마치 자신의 옆에 있는 것처럼 메소드를 호출(RMI:Remote Method Invocation)
Access Proxy(접근 프록시) Real Subject 역할의 기능에 대해서 엑세스 제한을 설정

이것으로

이번 학습을 마치겠습니다

그럼 이만-_-

반응형
LIST