Applied Design Patterns with Java

Structural :: Proxy (207) {C ch 15}

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


Motivation

One reason for controlling access to an object is to defer the full cost of its creation and initialization until actually needed. A document editor can embed graphical objects in a document. Some graphical objects, like large raster images, can be expensive to create. But opening a document should be fast, so it's best to avoid creating all the expensive objects at once when the document is opened. This isn't necessary anyway, because not all of these objects will be visible in the document at the same time. These constraints would suggest creating each expensive object on demand, which in this case occurs when an image becomes visible. But what is put in the document in place of the image? And how is the fact that the image is created on demand hidden, without complicating the editor's implementation? This optimization shouldn't impact the rendering and formatting code, for example. The solution is to use another object, an image Proxy, that acts as a stand-in for the real image. The Proxy acts just like the image and takes care of instantiating it when it's required.


The image
Proxy creates the real image only when the document editor asks it to display itself by invoking its Draw operation. The Proxy forwards subsequent requests directly to the image. It must therefore keep a reference to the image after creating it. Assume that images are stored in separate files. In this case, use the file name as the reference to the real object. The Proxy also stores its extent, that is, its width and height. The extent lets the proxy respond to requests for its size from the formatter without actually instantiating the image. The following class diagram illustrates this example in more detail.

The document editor accesses embedded images through the interface defined by the abstract Graphic class. ImageProxy is a class for images that are created on demand. ImageProxy maintains the file name as a reference to the image on disk. The file name is passed as an argument to the ImageProxy constructor. ImageProxy also stores the bounding box of the image and a reference to the real Image instance. This reference won't be valid until the Proxy instantiates the real image. The Draw() operation makes sure the image is instantiated before forwarding it the request. GetExtent() forwards the request to the image only if it's instantiated; otherwise ImageProxy returns the extent it stores.

Catalog Structural Prev Next