본문 바로가기

설계

[디자인 패턴] 프록시 패턴 (Proxy Pattern) - python 예제 코드

프록시 패턴은 객체 지향 디자인 패턴 중 하나로, 다른 객체에 대한 대리자(proxy)를 제공하여 해당 객체에 대한 간접적인 접근을 가능하게 합니다. 이 패턴은 프록시 객체를 통해 원본 객체에 접근하는 방법을 제어하므로, 프록시 객체를 통해 원본 객체에 대한 접근을 제한하거나, 캐싱, 인증, 로깅 등의 부가 기능을 추가할 수 있습니다.

1. 예제 코드


Python에서는 다음과 같이 프록시 패턴을 구현할 수 있습니다.

# 프록시 인터페이스
class Subject:
    def request(self):
        pass

# 실제 객체
class RealSubject(Subject):
    def request(self):
        print("RealSubject의 request() 메서드 호출")

# 프록시 객체
class Proxy(Subject):
    def __init__(self):
        self.real_subject = RealSubject()

    def request(self):
        self.pre_request()
        self.real_subject.request()
        self.post_request()

    def pre_request(self):
        print("Proxy의 pre_request() 메서드 호출")

    def post_request(self):
        print("Proxy의 post_request() 메서드 호출")

# 클라이언트
def main():
    proxy = Proxy()
    proxy.request()

if __name__ == "__main__":
    main()



위 코드에서 Subject는 프록시와 실제 객체의 공통 인터페이스를 정의합니다. RealSubject는 프록시가 감싸는 실제 객체를 나타냅니다. Proxy는 Subject를 구현하고, RealSubject를 감싸며, 클라이언트에서는 Proxy를 호출합니다.

Proxy는 RealSubject를 생성자에서 생성하여 감싸고 있으며, request() 메서드를 호출할 때는 pre_request()와 post_request() 메서드를 호출하여 부가 기능을 수행합니다. 이후 RealSubject의 request() 메서드를 호출하여 결과를 반환합니다.

main() 함수에서는 Proxy 객체를 생성하여 request() 메서드를 호출합니다. 결과적으로 RealSubject의 request() 메서드를 호출하지만, Proxy 객체를 통해 간접적으로 접근하게 됩니다.

2. 적용 예시

프록시 패턴은 다양한 프레임워크에서 사용되고 있습니다. 아래는 몇 가지 예시입니다.


1) Django 프레임워크의 캐시 프레임워크

Django의 캐시 프레임워크는 프록시 패턴을 사용하여 구현됩니다. 캐시 객체는 실제 캐시 메커니즘을 구현하는 실제 객체를 감싸는 프록시 객체입니다. 이를 통해 캐시 객체를 직접 사용하는 대신에 프록시 객체를 사용하여 캐시 메커니즘에 접근할 수 있습니다.


2) SQLAlchemy 프레임워크의 ORM


SQLAlchemy의 ORM은 프록시 패턴을 사용하여 구현됩니다. ORM은 데이터베이스 테이블을 클래스로 표현하는 객체 관계 매핑(Object-Relational Mapping)입니다. ORM은 실제 데이터베이스 연결을 처리하는 실제 객체를 감싸는 프록시 객체를 사용합니다.

이처럼 프록시 패턴은 다양한 프레임워크에서 사용되고 있으며, 이를 통해 부가 기능을 추가하거나 객체에 대한 접근을 제어할 수 있습니다.

3. 장점

  • 보안성이 높습니다. 프록시 객체를 통해서만 실제 객체에 접근할 수 있으므로, 객체에 대한 접근을 제어할 수 있습니다.
  • 부가 기능 추가가 용이합니다. 프록시 객체에서 원본 객체의 메소드를 호출하기 전에 부가 기능(로깅, 인증, 캐싱 등)을 추가할 수 있습니다.
  • 원본 객체를 수정하지 않고도 객체의 기능을 확장할 수 있습니다. 따라서 객체의 유지보수성과 재사용성이 높아집니다.

4. 단점

  • 프록시 객체를 생성하고 사용하기 때문에, 성능에 영향을 미칠 수 있습니다. 이는 프록시 객체의 생성과 메소드 호출 시의 오버헤드 때문입니다.
  • 코드의 복잡도가 높아질 수 있습니다. 프록시 객체가 추가되면 코드가 복잡해지므로, 디자인 패턴을 이해하지 않은 사람은 이해하기 어렵습니다.
  • 프록시 객체를 사용하여 객체를 간접적으로 호출하므로, 디버깅이 어렵습니다.

따라서, 프록시 패턴은 객체의 보안성과 확장성을 높일 수 있으나, 성능 저하와 코드 복잡도 등의 단점도 고려해야 합니다.