PHpullh

PYTHON · 디자인패턴

프록시 패턴

프록시 패턴으로 객체 접근을 제어하고 지연 로딩, 캐싱, 접근 제어를 구현합니다.

디자인패턴고급proxy프록시지연 로딩캐싱

핵심 설명

프록시 패턴으로 객체 접근을 제어하고 지연 로딩, 캐싱, 접근 제어를 구현합니다.

Python code

from abc import ABC, abstractmethod
import time

class Database(ABC):
    @abstractmethod
    def query(self, sql: str) -> list: ...

class RealDatabase(Database):
    def __init__(self):
        print("  [DB] 무거운 연결 수립 중...")
        time.sleep(0.01)
        self._connected = True

    def query(self, sql: str) -> list:
        return [{"result": f"데이터: {sql}"}]

# 지연 로딩 프록시
class LazyDatabaseProxy(Database):
    def __init__(self):
        self._db: RealDatabase | None = None

    def _get_db(self) -> RealDatabase:
        if self._db is None:
            self._db = RealDatabase()
        return self._db

    def query(self, sql: str) -> list:
        return self._get_db().query(sql)

# 캐싱 프록시
class CachingProxy(Database):
    def __init__(self, db: Database):
        self._db = db
        self._cache: dict[str, list] = {}

    def query(self, sql: str) -> list:
        if sql not in self._cache:
            print(f"  [캐시 MISS] {sql}")
            self._cache[sql] = self._db.query(sql)
        else:
            print(f"  [캐시 HIT] {sql}")
        return self._cache[sql]

# 사용
print("=== 지연 로딩 ===")
db = LazyDatabaseProxy()
print("DB 객체 생성 (아직 연결 안 됨)")
print(db.query("SELECT 1"))  # 이 시점에 연결

print("\n=== 캐싱 ===")
cached = CachingProxy(LazyDatabaseProxy())
cached.query("SELECT * FROM users")  # MISS
cached.query("SELECT * FROM users")  # HIT
cached.query("SELECT * FROM orders") # MISS

학습 팁

프록시 패턴은 원본 객체의 인터페이스를 그대로 유지하므로 클라이언트 코드 변경 없이 기능을 추가할 수 있습니다.

주의할 점

프록시의 캐시를 무효화하지 않으면 오래된 데이터를 반환합니다. TTL이나 수동 무효화 전략을 구현하세요.

자주 묻는 질문

프록시 패턴란 무엇인가요?

프록시 패턴으로 객체 접근을 제어하고 지연 로딩, 캐싱, 접근 제어를 구현합니다.

프록시 패턴 학습 시 주의할 점은 무엇인가요?

프록시의 캐시를 무효화하지 않으면 오래된 데이터를 반환합니다. TTL이나 수동 무효화 전략을 구현하세요.