Proxy Pattern

📢 This article was translated by gemini-3-flash-preview

Proxy Pattern - Object Structural Pattern

Intent

Provide a surrogate or placeholder for another object to control access to it.

Structure

Proxy Pattern

Participants:

  • Proxy: Maintains a reference that lets the proxy access the real subject. It provides an interface identical to Subject’s so that a proxy can be substituted for the real subject. It controls access to the real subject and may be responsible for creating and deleting it.
  • Subject: Defines the common interface for RealSubject and Proxy so that a Proxy can be used anywhere a RealSubject is expected.
  • RealSubject: Defines the real object that the proxy represents.

Applicability

The Proxy pattern is useful when you need a more versatile or sophisticated reference to an object than a simple pointer. Common scenarios include:

  • Remote Proxy: Provides a local representative for an object in a different address space.
  • Virtual Proxy: Creates expensive objects on demand.
  • Protection Proxy: Controls access to the original object. Useful when objects should have different access rights.
  • Smart Reference: A replacement for a bare pointer that performs additional actions when an object is accessed. Typical uses include:
    • Reference counting for an object so it can be automatically freed when there are no more references.
    • Loading a persistent object into memory when it’s first referenced.
    • Checking that the real object is locked before it’s accessed to ensure no other object can change it.

Example

An agent proxy for buying items.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class ProxyPattern {
    public static void main(String[] args) {
        RealSubject realSubject = new RealSubject();
        Proxy proxy = new Proxy(realSubject);

        proxy.buy();
    }
}

interface Subject{
    public void buy();
}

class Proxy implements Subject{
    protected RealSubject realSubject;

    public Proxy(RealSubject realSubject){
        this.realSubject = realSubject;
    }

    @Override
    public void buy() {
        System.out.println("prepare");
        realSubject.buy();
        System.out.println("complete");
    }
}

class RealSubject implements Subject{

    @Override
    public void buy() {
        System.out.println("Money");
    }
}