Design Pattern

Proxy Pattern

Clean Java-only production-ready implementation.


You need to control access to an object. The proxy acts as a surrogate, doing something before/after delegating to the real object — lazy loading, access control, logging, caching, or remote communication.

// ─── EXAMPLE 1 ──────────────────────────────────────────────────────────────
// WHAT WE ARE IMPLEMENTING:
// A network video-loading gateway implementing an internal cache wrapper
// around a slow cloud storage SDK.
//
// WHERE THE PROXY FITS IN:
// VideoService is the Subject. RealVideoService is the Real Subject.
// ProxyVideoService is the Cache Proxy controlling access and caching
// results.
// ────────────────────────────────────────────────────────────────────────────
// --- Subject ---
interface Image {
    void display();
}

// --- Real subject ---
class RealImage implements Image {
    private final String filename;

    public RealImage(String filename) {
        this.filename = filename;
        loadFromDisk();  // Expensive operation
    }

    private void loadFromDisk() {
        System.out.println("  [RealImage] Loading " + filename + " from disk...");
        try { Thread.sleep(500); } catch (InterruptedException ignored) {}
    }

    public void display() {
        System.out.println("  [RealImage] Displaying " + filename);
    }
}

// --- Proxy (virtual proxy — lazy load) ---
class ProxyImage implements Image {
    private final String filename;
    private RealImage realImage;

    public ProxyImage(String filename) { this.filename = filename; }

    public void display() {
        if (realImage == null) {
            realImage = new RealImage(filename);  // Lazy initialization
        }
        realImage.display();
    }
}

// --- Protection proxy ---
class ProtectedImageProxy implements Image {
    private final ProxyImage proxyImage;
    private final String userRole;

    public ProtectedImageProxy(String filename, String userRole) {
        this.proxyImage = new ProxyImage(filename);
        this.userRole = userRole;
    }

    public void display() {
        if (!userRole.equals("ADMIN")) {
            System.out.println("  [Proxy] Access denied: " + userRole + " cannot view " + proxyImage);
            return;
        }
        proxyImage.display();
    }
}

public class Main {
    public static void main(String[] args) {
        System.out.println("--- Virtual Proxy (lazy load) ---");
        Image img = new ProxyImage("photo.jpg");
        System.out.println("Image created — no loading yet");
        img.display();  // Loads only now

        System.out.println("\n--- Protection Proxy ---");
        Image protectedImg = new ProtectedImageProxy("confidential.png", "USER");
        protectedImg.display();  // Denied

        Image adminImg = new ProtectedImageProxy("confidential.png", "ADMIN");
        adminImg.display();  // Allowed
    }
}