SwadhyAI Notes

All Low-Level Design notes

Structural · same type, control access / lifetime / location

Proxy

A is a structural pattern that places a stand-in in front of a real object. The stand-in implements the same interface and controls when the real object is created, whether a call is allowed, or where the work actually runs.

A concrete example: a photo gallery shows fifty frames. You do not load fifty 12MB originals on page open. Each frame is an Image as far as the UI cares. Behind the frame, a stand-in loads the file the first time someone clicks display().

Timeline: page open vs first click

  1. T+0

    Gallery mounts

    Fifty LazyImage objects exist. Zero DiskImage. Heap holds frames, not originals.

  2. T+click

    First display()

    Proxy creates DiskImage(path), then forwards. Cost is paid once, on demand.

  3. Later

    Second display()

    Proxy already holds the real instance. Forward only. No second load.

Diagram text: the exact Mermaid definition below preserves the nodes, labels, and connections. Enable JavaScript to view the rendered diagram.
Read the diagram definition
sequenceDiagram
    participant UI
    participant P as LazyImage
    participant D as DiskImage

    Note over UI,D: page open — fifty frames, no 12MB loads
    UI->>P: display()
    P->>D: new DiskImage(path)
    D-->>P: pixels ready
    P-->>UI: show
    UI->>P: display() again
    P->>D: display()
    Note over P,D: real instance already lives

Core question

Do I need a stand-in that looks like the real object but controls when, whether, or where it runs?

Keep the real type. Name the control. Forward after the check. Do not leak the real instance. The stand-in must stay .

Three kinds of control — pick one sentence

— not yet

Delay construction. DiskImage is created on first display(). Lifetime is the point.

— only if

Session must be allowed. Then forward. Whether is the point, not a log line.

— over there

Local stub, network hop, same Repository type. Location is the point.

Java sketch: virtual proxy — load on first display

java
interface Image {
  void display();
}

class DiskImage implements Image {
  DiskImage(String path) { loadFromDisk(path); }
  public void display() { /* show pixels */ }
  private void loadFromDisk(String path) { /* expensive */ }
}

class LazyImage implements Image {
  private final String path;
  private Image real;

  LazyImage(String path) { this.path = path; }

  public void display() {
    if (real == null) real = new DiskImage(path);
    real.display();
  }
}

Java sketch: protection proxy — same type, access check

java
interface Documents {
  String read(String id);
}

class StoreDocuments implements Documents {
  public String read(String id) { /* load body */ }
}

class AccessProxy implements Documents {
  private final Documents inner;
  private final Session session;

  public String read(String id) {
    if (!session.canView(id)) throw new SecurityException(id);
    return inner.read(id);
  }
}

Decorator’s diagram, different intent

Both wrap. Both keep the type. Say the sentence. If you cannot name the control (lazy / ACL / remote), you may want Decorator.

ProxyDecorator
Sentenceonly if / not yet / over therealso do X (log, retry, compress)
Inner objectoften created later by the proxyhanded in, already alive
Stackingrarely nest three proxiesnest three decorators on purpose
Client asked forcontrol of access, lifetime, locationextra behavior
Leak testmust not hand out DiskImageinner is already a known Notifier

Still not Adapter or Facade

vs Adapter

Adapter changes the interface. Proxy keeps it. If LazyImage cannot be used wherever Image is used, you translated types — that is Adapter, or a leaky helper. “The type is already Image” rules out Adapter in one sentence.

vs Facade

Facade hides many classes behind one simpler method. Proxy is one-to-one with the real subject. A gallery proxy does not sequence Inventory and Mailer. See Adapter vs Facade for the shape-vs-count split; this page is the stand-in.

How to implement it (four steps)

  1. 01

    Keep the real type

    Proxy implements Image, Document, Repository — the caller does not change.

  2. 02

    Name the control

    Lazy create, deny access, remote hop, or a smart count. If you cannot name it, you may want Decorator.

  3. 03

    Forward after the check

    Load, authorize, or marshal — then call the real object. Do not reinvent its job.

  4. 04

    Do not leak the real instance

    If callers can grab DiskImage and skip the proxy, the stand-in was decoration.

Common mistakes

A logging wrapper named Proxy

If the inner object already exists and you only add a log line, that is Decorator. Proxy is for access, lazy creation, or a remote stand-in. Same diagram, different reason.

Changing the interface in the stand-in

If the proxy cannot be used wherever the real object is used, it is an Adapter. Callers should still see Image, Documents, or Repository.

getRealImage() on the proxy

The UI will skip the stand-in. Hide DiskImage. Construction stays inside LazyImage.

How to explain this in an interview

“This is a virtual proxy so we do not pay for DiskImage until display. It is not a decorator — we are not adding logging. It is not an adapter — the type is already Image. It is not a facade — there is one real subject, not a subsystem.”
  1. Gallery of 50 photos: what exists at T+0, and what is created on first click?
  2. AccessProxy vs LoggingNotifier: same class diagram. Write the one sentence that tells them apart.
  3. After Stripe is adapted to Payable, you want retry. Is that this page or Decorator?

Takeaway

Proxy is a stand-in with the same type whose job is control: not yet, only if, or over there. Also-do-X is Decorator. Wrong shape is Adapter. Too many collaborators is Facade. That sentence is what you are graded on.