Skip to content

The Surrogate for Controlled Access

A stand-in that controls access to the real object

Builds on Interfaces

Stage 3core2 min read

The Unprotected Resource Problem

In this design, the client calls the heavy service directly, with nothing in between. This creates a "choke point" (a place where everything gets stuck). Costly work is repeated for no reason, and nothing controls who can get data or how.


1. Real-Life Coding Example

Imagine you are building a video streaming app (think YouTube or Netflix) where users can download videos. Many users may ask for the same video. The same user may also ask again.

If the app downloads the video from the internet every single time, it causes:

  • Unnecessary network calls: Repeatedly hitting the server for the same data.
  • Longer wait times: Users wait for a full download even if the data was fetched a moment ago.
  • Wasted bandwidth: This costs money for both the service provider and the user.

2. Key Issues in this Design

Lack of Caching (Redundant Execution)

  • The Issue: Nothing stores videos that were already downloaded.
  • The Impact: The same video is downloaded again and again, even if it is already available locally. This wastes computing work and network use.

Missing Access Control & Filtering

  • The Issue: The RealVideoDownloader is called directly. Nothing checks the caller first.
  • The Impact: Any video URL is downloaded. There is no place to add content filtering, premium user checks, or security rules.

Tight Client Coupling

  • The Issue: The client code uses the RealVideoDownloader class directly. The Before code has no VideoDownloader interface.
  • The Impact: You cannot intercept, log, or change the download behavior (e.g., add "retry" logic) without editing the downloader's own code.

Inefficient Resource Management

  • The Issue: Every request runs the full download again. The repo code creates one downloader and calls it twice, and both calls download.
  • The Impact: This means repeated high cost, especially when the "Real Subject" (the real object behind the proxy) is expensive to set up.

3. Structural Analysis

ComponentStatusObservation
Real SubjectExposedPerforms heavy network I/O for every single request.
ClientTightly CoupledCreates and calls the expensive resource itself.
Data FlowUnoptimizedNo middle layer to check whether the request needs to reach the network at all.

4. Summary of the "Smell"

Watch for this: a client calls a costly or sensitive object directly, with no protective layer. The old code called RealVideoDownloader for every request, so it downloaded the same content again and again. The Proxy Pattern adds a "Placeholder" in front that manages these calls.

In this topic

Before code1 file

Before/Main.java41 linesGitHub
package DesignPatterns.StructuralPatterns.ProxyDesignPattern.Before;/** * PROBLEM: The RealSubject is exposed directly to the client. * There is no middleman to handle "cross-cutting concerns" like * security, logging, or caching. */class RealVideoDownloader {  public String downloadVideo(String videoUrl) {    // ISSUE 1: Heavy Operation    // This represents a costly network call or disk I/O.    // Without a proxy, we perform this every single time.    // ISSUE 2: Missing Access Control    // Any user can call this method. There is no logic to check    // if the user is a "Premium" member or has a valid API key.    // ISSUE 3: Missing Redundancy Check (Caching)    // If 100 users ask for the same viral video, we download it 100 times.    System.out.println("Downloading video from URL: " + videoUrl);    return "Video content from " + videoUrl;  }}public class Main {  public static void main(String[] args) {    // Client interacts directly with the expensive resource.    RealVideoDownloader realVideoDownloader = new RealVideoDownloader();    // Request 1: Remote download happens.    realVideoDownloader.downloadVideo("https://video.com/proxy-pattern");    // Request 2: The exact same URL!    // PROBLEM: We are re-downloading because the class has no memory/cache.    realVideoDownloader.downloadVideo("https://video.com/proxy-pattern");  }}

Done with this topic?

How well do you know it?

PreviousDesign Pattern: Composite (Structural)