What It Is
The Proxy pattern puts a stand-in with the same interface in front of a real object. Callers talk to the proxy as if it were the real thing; the proxy decides when and how to involve the original.
Common jobs for a proxy: caching answers, checking access, delaying expensive creation, counting calls.
Example: A Caching Proxy
The real weather service is slow. The proxy answers repeated questions from its cache and only calls the service for new ones — both classes satisfy the very same Weather protocol, so callers cannot tell them apart.
The stand-in that remembers
The first Paris question reaches the remote service; the second is answered from the cache — the "calling the remote service" line prints only once.
Output: complete Python program
from typing import Protocol
class Weather(Protocol):
def forecast(self, city: str) -> str: ...
# The real service is slow and expensive.
class WeatherService:
def forecast(self, city: str) -> str:
print(" (calling the remote service...)")
return "sunny in " + city
# The proxy stands in front and caches answers.
class CachedWeather:
def __init__(self) -> None:
self.service = WeatherService()
self.cache: dict[str, str] = {}
def forecast(self, city: str) -> str:
cached = self.cache.get(city)
if cached is not None:
return cached + " (from cache)"
answer = self.service.forecast(city)
self.cache[city] = answer
return answer
w = CachedWeather()
print(w.forecast("Paris"))
print(w.forecast("Paris"))
When to Use It
Use it to add caching, access control, laziness or metering in front of something you cannot or should not change — especially remote or expensive resources.
Skip it when you own the object and the behavior belongs inside it. A proxy is for controlling access; a decorator is for adding behavior in layers — pick the intent that matches.
Pros and Cons
Pros: callers need no changes at all; expensive work is skipped or controlled in one place.
Cons: hidden behavior — a caller may get a cached answer without knowing; stale caches and surprise denials are debugged behind an innocent-looking interface.