본문 바로가기
My Image
프로그래밍/Design_Pattern

[Design_Pattern] 프록시 패턴(Proxy Pattern)

by Lim-Ky 2017. 8. 25.
반응형

안녕하세요. Limky 입니다. 이번 시간은 프록시 패턴(Proxy Pattern)에 대해서 알아보겠습니다.

 

Proxy는 우리말로 대리자, 대변인 이라는 뜻입니다. 대리자, 대변인은 다른 누군가를 대신해서 그 역할을 수행하는 존재입니다. 프로그램에서 봤을 때도 똑같습니다. 프록시에게 어떤 일을 대신 시키는 것입니다. 

 

 

구체적으로 인터페이스를 사용하고 실행시킬 클래스에 대한 객체가 들어갈 자리에 대리자 객체를 대신 투입해 클라이언트 쪽에서 실제  실행시킬 클래스에 대한객체를 통해 메서드를 호출하고 반환 값을 받는지, 대리자 객체를 통해 메서드를 호출하고 반환 값을 받는지 전혀 모르게 처리하는 것입니다. 

 

일종의 프록시는 비서역할을 하는 것 같네요. 중요한 것은 흐름제어만 할 뿐 결과값을 조작하거나 변경시키면 안됩니다. 제가 비서에게 대신 연락처 목록을 정리해서 달라고 지시했다면, 그 연락처 목록을 정리한 결과만 컴퓨터에서 받아서 전달해줘야 연락처를 수정하거나, 전화를 하면 안되겠죠? 마찬가지로 프록시도 자신의 의견을 반영하는 것을 목적으로 하지 않고 제어의 흐름을 변경하거나 다른 로직을 수행하기 위해 사용하는 것입니다. 

하나 더 추가적으로 Proxy 패턴에 특징을 알아봅시다.

 

  • 대리자는 실제 서비스와 같은 이름의 메서드를 구현한다. 이때 인터페이스를 사용한다.
  • 대리자는 실제 서비스에 대한 참조 변수를 갖는다(합성)
  • 대리자는 실제 서비스의 같은 이름을 가진 메서드를 호출하고 그 값을 클라이언트에게 돌려준다.
  • 대리자는 실제 서비스의 메서드 호출 전후에도 별도의 로직을 수행할 수도 있다.

 

 

자 그럼 Proxy에 대한 디자인 패턴 테이블을 봅시다.

 

 

느낌이 오시나요?? 클라이언트가 어떤 일에 대한 요청(RealSubject의 request()메서드 호출)을 하면, Proxy가 대신 RealSubject의 request()메서드 호출을 하고 그 반환 값을 클라이언트에게 전달합니다.

 

간단한 예제를 통해 이해해보겠습니다. 

 

 

 

Main 에서 Service의 runSomething()메서드를 직접 호출 하지 않고 Proxy에게 대신 시킵니다.

그럼 Proxy는 Service의 인스턴스를 가지고 있으면서 직접 Service의 runSomething()메서드를 호출하고 그 반환 값을 요청자 Main에게 넘겨줍니다. 코드로 구현하면 아래와 같습니다.

 

 

 

IService.java

public interface IService {
	String runSomething();
}

Service.java

public class Service implements IService {
	@Override
	public String runSomething() {
		return "서비스 짱!!!";
	}
}

Proxy.java

public class Proxy implements IService {
	IService service1;

	@Override
	public String runSomething() {
		System.out.println("호출에 대한 흐름 제어가 주목적, 반환 결과를 그대로 전달");
		service1 = new Service();
		return service1.runSomething();
	}
}

Main.java

public class Main {  	
public static void main(String[] args) { 		
	//직접 호출하지 않고 프록시를 호출한다. 		
	IService proxy = new Proxy(); 		
	System.out.println(proxy.runSomething()); 	
	}
}
}

 

위 코드를 잘 보면 인터페이스를 중간에 두어 구체클래스들에게 영향을 받지 않게 설계했습니다. 또 직접 접근하지 않고 Proxy를 통해서 한번 더 우회해서 접근하도록 되어있습니다. (제어 흐름을 조정하기 위함) 이는 일전에 배웠던 OCP, DIP 설계 원칙이 녹아져 있음을 확인 할 수 있습니다.

 

객체 지향 설계 원칙에 대해서 잘 모르시는 분들은 아래를 참고하시면 됩니다.

2017/08/24 - [Java] - [Java] 객체 지향 설계란? (SOLID)

 

Proxy는 결국 직접 실행 메서드를 호출하는 것을 피하면서 취하고 싶었던 것은 흐름 제어라고 했습니다. 흐름제어가 왜 필요할까요??? 요즘 유행하는 게임 배틀그라운드를 생각해봅시다. 유저가 죽고 나서 다시 살아 날 때 로딩시간이 걸립니다. 데이터가 큰 이미지나 그래픽을 로딩하는데 시간이 걸리기 때문이죠 이럴 경우 유저는 짜증날 겁니다. 계속 아무것도 안하고 기다려야 하니까 이럴때 프록시는 제어 흐름을 통해 큰 데이터가 로딩 될 때 까지 현재까지 완료된 것을 우선적으로 보여줍니다. 즉 배틀그라운드에서 비행기 타기 전 사람들이 어느 한정된 공간에서 캐릭터를 움직일 수 있게라도 해주는 것이죠... 일단 할 이야기가 많으니 Proxy 패턴은 이 정도로 마무리 하겠습니다. 

 

 

 

 

 

 

 

 

 

 

반응형

댓글