소스 코드를 기록하는 남자

프록시 패턴(Proxy Pattern)

디자인 패턴

프록시라는 말은 대변인이란 의미를 가진다. 누군다를 대신해서 수행한다는 의미로서 디자인 패턴에서도 이와 같은 방식으로 적용된다. 객체지향스럽지 않은가? 현실 고증이 오진다.

 

먼저 프록시가 적용되지 않은 코드를 보자.

 

[Service]

package proxyPattern;

public class Service {
    public String runProcess() {
        return "Process";
    }
}

[ClientWithNoProxy]

public class ClientWithNoProxy {
    public static void main(String[] args)
    {
        Service service = new Service();
        System.out.println(service.runProcess());
    }
}

위와 같은 코드가 있다면, Client 에서 runProcess() 메소드를 직접 호출하는 것을 볼 수 있다.

그럼 프록시 패턴이 적용된다면 어떻게 될까? 프록시 패턴의 경우 실제 서비스 객체가 가진 메서드와 같은 이름의 메서드를 사용하고, 이 목적을 달성하기 위해 인터페이스를 사용한다.

 

인터페이스를 사용하면 서비스 객체가 들어갈 자리에 대리자 객체를 대신 투입하여 클라이언트 쪽에서 실제 서비스 객체를 통해서 메소드를 호출하고 반환값을 받는지, 대리자 객체를 통해 메소드를 호출하고 반환값을 받는지 전혀 모르게 처리할 수도 있다.

 

코드를 한번 살펴보자.

 

[IService]

package proxyPattern;

public interface IService {
    String runProcess();
}

[Service]

package proxyPattern;

public class Service implements IService{
    @Override
    public String runProcess() {
        return "Process";
    }
}

[Proxy]

package proxyPattern;

public class Proxy implements IService {
    IService service1;

    public String runProcess() {
        System.out.println("호출에 대한 흐름 제어가 주목적이며, 반환 결과를 그대로 전달한다");

        service1 = new Service();
        return service1.runProcess();
    }
}

[ClientWithProxy]

package proxyPattern;

public class ClientWithProxy {
    public static void main(String[] args)
    {
        IService proxy = new Proxy();
        System.out.println(proxy.runProcess());
    }
}

 

이전 코드에서는 Service service로 객체를 만들어 직접 선언했지 않았는가? 하지만 프록시 패턴을 사용하게 되면 대리자 호출이 가능해진다. 자! 프록시 패턴의 중요 포인트를 확인하고 마무리하겠다.

  • 대리자는 실제 서비스와 같은 이름의 메서드를 구현한다. 인터페이스를 사용한다.

  • 대리자는 실제 서비스에 대한 참조 변수를 갖는다.(합성을 사용)

  • 대리자는 실제 서비스의 같은 이름을 가진 메서드를 호출하고 그 값을 클라이언트에게 돌려준다.

  • 대리자는 실제 서비스의 메서드 호출 전후에 별도의 로직을 수행할 수도 있다.

 

프록시 패턴을 아까 뭐라고 했는가? 대변인이라 하지 않았는가? 대변인이 하는 일이 뭔가를 생각해보면 본인의 의견을 이야기하는 것이 아니라 어떤 회사, 정부, 기관 등의 의견을 대변할 뿐 자신의 의견을 더하거나 빼거나 가미하지 않는다. 프록시 패턴실제 서비스 메서드의 반환값에 아무런 가감하지 않는 것을 보면 알 것이다.

 

프록시 패턴의 목적은 아래와 같다.

 

 

제어의 흐름을 변경하거나 다른 로직을 수행하기 위해 사용

 

 

그럼 프록시 패턴을 한 문장으로 정의해보자.

 

 

제어 흐름을 조정하기 위한 목적으로 중간에 대리자를 두는 패턴

 

 

이해가 됐으면 좋겠다. 이 예제에서 사용된 프록시 패턴은 이전의 SOLID를 기억나게 할 것임이 분명하다.

여기에는 개방 폐쇄 원칙과 의존 역전 원칙이 적용된 설계 패턴이기 때문이다.