What It Is
The Proxy pattern puts a stand-in with the same interface in front of a real object. Callers talk to the stand-in as if it were the real thing; the stand-in decides when and how to involve the original.
Common jobs for such a stand-in: caching answers, checking access, delaying expensive creation, counting calls.
Note: name the class after its job — CachedWeather, ReadOnlyAccount — never Proxy. That name already belongs to a built-in JavaScript object.
Example: A Caching Proxy
The real weather service is slow. The stand-in answers repeated questions from its Map cache and only calls the service for new ones — behind the very same Weather interface.
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, and the second answer ends with (from cache).
Output: TypeScript file and captured output
interface Weather {
forecast(city: string): string
}
// The real service is slow and expensive.
class WeatherService implements Weather {
forecast(city: string): string {
console.log(" (calling the remote service...)")
return "sunny in " + city
}
}
// The stand-in sits in front of the service and caches answers.
class CachedWeather implements Weather {
private service: Weather
private cache = new Map<string, string>()
constructor(service: Weather) {
this.service = service
}
forecast(city: string): string {
const cached = this.cache.get(city)
if (cached !== undefined) {
return cached + " (from cache)"
}
const answer = this.service.forecast(city)
this.cache.set(city, answer)
return answer
}
}
const weather: Weather = new CachedWeather(new WeatherService())
console.log(weather.forecast("Paris"))
console.log(weather.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 — they keep the same interface; 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.