Proxy

Design patterns / Structural patterns
image

type
  IImage = interface
    procedure Display;
  end;

  TRealImage = class(TInterfacedObject,
    IImage)
  private
    FFileName: string;
  public
    constructor Create(
      const AFileName: string);
    procedure Display;
  end;

  //proxy delays the heavy object
  //until it is really needed
  TImageProxy = class(TInterfacedObject,
    IImage)
  private
    FFileName: string;
    FReal: IImage;
  public
    constructor Create(
      const AFileName: string);
    procedure Display;
  end;

constructor TRealImage.Create(
  const AFileName: string);
begin
  FFileName := AFileName;
  WriteLn('loading ', FFileName);
end;

procedure TRealImage.Display;
begin
  WriteLn('display ', FFileName);
end;

constructor TImageProxy.Create(
  const AFileName: string);
begin
  FFileName := AFileName;
end;

procedure TImageProxy.Display;
begin
  if FReal = nil then
    FReal := TRealImage.Create(FFileName);
  FReal.Display;
end;

var
  Image: IImage;
begin
  Image := TImageProxy.Create('photo.png');
  WriteLn('proxy created, nothing loaded');

  Image.Display;
  //loading photo.png
  //display photo.png
end.


Provide a surrogate or placeholder for another object to control access to it. The proxy implements the interface of the original object.
Read more

The problem. A document contains many large pictures. If the program loads all of them when the document opens, opening is slow, although the user sees only the first page. The code that shows the pictures should stay the same. But loading must wait until a picture is really needed.

The idea. A proxy takes the place of another object, the real subject. It has the same interface, so the client sees no difference between them. The proxy decides when and how the real subject is used. This kind, a virtual proxy, creates the real subject only on the first request and then forwards every call to it. Other kinds of proxy check access rights, keep a cache or reach an object on another computer.

How to read the example. The real subject is an image that is costly to create. The proxy keeps only the file name and an empty place for the image. In most languages the client first asks for the file name, and the proxy answers alone. When the client asks to draw, the proxy creates the real image, keeps it and forwards the call. The client works only with the proxy. In some languages the output also shows the moment when the real image is loaded.

When to use it. Use Proxy to control access to an object without changing the object or its clients. Typical tasks are to delay a costly creation, to check rights or to count calls. Do not use it when the object is cheap and always needed: the extra level only slows the code.

A common mistake. Not keeping the created object. The proxy then creates a new real subject on every call, and the saving is lost.