본문 바로가기

PROGRAMMING/Design Pattern

[GoF] 프록시 (Proxy) 패턴

프록시 (Proxy) 패턴 구조 패턴

사용할 객체의 제어권을 위임함으로써, 객체에 대한 클라이언트의 요청을 대신 받아 전달합니다.



프록시(Proxy) 란 대리권을 의미하는 단어로써, 프록시 패턴은 객체에 대한 제어권을 위임받는 별도의 객체를 통해 객체에 대한 클라이언트의 요청을 대리하여 수행한다. 그렇다면, 프록시는 구체적으로 어떻게 클라이언트의 요청을 대리하여 수행하는것인가?

대표적으로 레스토랑의 예를 들어보겠다. 레스토랑은 고객이 요청한 음식을 셰프가 제공하는 형태의 업체이다. 하지만, 대부분의 경우에는 셰프가 직접 음식을 고객으로부터 요청받지 않고, 요리된 음식을 고객의 테이블에 가져다놓지도 않는다. 고객과 셰프 사이의 중개인으로써 웨이터가 존재한다. 웨이터는 고객으로부터 요청받은 음식을 셰프에게 전달하고, 요리된 음식을 주방으로부터 가져와 테이블로 가져다놓는 역할을 한다. 결국 고객은 웨이터로만 통해서 모든 서비스를 받게 되었다. 셰프의 얼굴이 어떻게 생겼는지도 모르는 채로 말이다.

이처럼 프록시 객체는 웨이터와 같이 클라이언트와 객체 사이의 중개를 담당한다. 클라이언트로부터의 요청을 대신 받고, 이를 실제 객체에게 전달한다. 그러므로 프록시는 클라이언트에게 실제 객체와 동일한 인터페이스를 제공하나, 실제 객체에 대한 정보를 클라이언으로부터 은닉시킨다. 또한 프록시에 별도의 로직을 추가함으로써 실제 객체의 흐름을 제어할수도 있다.

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
31
32
33
34
35
36
37
public class Proxy
{
    public interface ISubject
    {
        void Operate();
    }
 
    public class Subject : ISubject
    {
        public void Operate()
        {
            Console.WriteLine("Operate Subject");
        }
    }
 
    public class ProxySubject : ISubject
    {
        private Subject _subject;
 
        public ProxySubject(Subject subject)
        {
            _subject = subject;
        }
 
        public void Operate()
        {
            _subject.Operate();
        }
    }
 
    public static void Main(string[] args)
    {
        ISubject proxy = new ProxySubject(new Subject());
 
        proxy.Operate();
    }
}
cs

클라이언트는 Subject 대신 ProxySubject에게 인터페이스를 제공받아 Operate()를 호출하였다. 그러자 ProxySubject는 이미 할당받은 Subject에게 Operate()를 호출하면서 "Operate Subject"를 출력하였다. 결국 Subject에게 직접 Operate()를 호출하는것과 같은 결과를 도출하지만, 클라이언트는 Subject의 정보를 직접 가져올 수 없다.