Back Home Up Next


1 Purpose

2 Problem Description

3 Domain Definitions

4 Elisa Components

1  Purpose

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


2  Problem Description

One reason for controlling access to an object is to defer the full cost of its creation and initialization until we actually need to use it. Consider a document editor that 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 we should 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 do we put in the document in place of the image? And how can we hide the fact that the image is created on demand so that we don't complicate 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.

Let's assume that images are stored in separate files. In this case we can 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.

3  Domain Definitions

We will transform the top-level relations into a set of corresponding domain definitions:

Graphic = Image | ImageProxy

Image = imageImp + extent + . . .

ImageProxy = fileName + extent + image. . .

The next step is to translate the domain definitions into a number of Elisa components. In addition, we will use skeletons of definitions as shown in the preceding domain relationships.

4  Elisa components 

Based on the domain definitions a set of related components are derived. The first component implements  a skeleton of the  Graphic domain.

component Graphics;
type Graphic = category(Image, ImageProxy);

     Draw(Graphic)      -> nothing;

     GetExtent(Graphic) -> Point; 

     Store(Graphic)     -> nothing;

     Load(Graphic)      -> nothing;
        . . .

            <<implementations of >>

     Draw(Image:image) = Draw(image);

     Draw(ImageProxy:imageProxy) = Draw(imageProxy);


     GetExtent(Image:image) = GetExtent(image);

     GetExtent(ImageProxy:imageProxy) = GetExtent(imageProxy);


     Store(Image:image) = Store(image);

     Store(ImageProxy:imageProxy) = Store(imageProxy);


     Load(Image:image) = Load(image);

     Load(ImageProxy:imageProxy) = Load(imageProxy);

        . . .

end component Graphics;

The following component is a skeleton example of a Image


component Images;
type Image;

     CreateImage( )  -> Image;
     Draw(Image)     -> nothing;

     GetExtent(Image)-> Extent; 
     Store(Image)    -> nothing;

     Load(Image)     -> nothing;

       . . .

            <<implementations of >>
     CreateImage( ) = Image:[ imageImp ... extent...];
     Draw(image) = ...;

     GetExtent(image) = ...; 
     Store(image) = ...;

     Load(image) = ...;

        . . .

end component Images;

The following component is a skeleton example of a ImageProxy


component ImageProxys;
type ImageProxy;

     CreateImageProxy( )   -> ImageProxy;
     Draw(ImageProxy)      -> nothing;

     GetExtent(ImageProxy) -> Extent; 
     Store(ImageProxy)     -> nothing;

     Load(ImageProxy)      -> nothing;

       . . .

            <<implementations of >>
     CreateImageProxy( ) = ImageProxy:[ fileName ... extent... image ...];
     Draw(imageProxy) = [... if invalid(image) then LoadImage(fileName)

                                                 else Draw(imageProxy.image);

     GetExtent(imageProxy) = [... if invalid(image) then return(imageProxy.extent)

                                                      else GetExtent(imageProxy.image);...]; 
     Store(imageProxy) = ...;

     Load(imageProxy) = ...;

        . . .

end component ImageProxys;



Back Home Up Next

  Part 5: Design Patterns   Proxy


Home | Highlights of Elisa | Integrating Different Paradigms | Getting Started with Elisa | Demo's  | What is Domain Orientation | Bibliography | Copyright | News | Contact | Contents

Language Description:

Lexical Elements | Basic Data Types and Expressions | Definitions | Streams | Backtracking | Statements and Special Expressions | Arrays | Lists | Descriptors | Components | Collections | Generic Components | Terms | Categories | Types | Built-in Definitions | Higher-order Definitions | External Interfaces | Index 

Data Structures: Sequences | Examples involving Lists | Trees | Graphs | Searching State Spaces | Language Processing | Knowledge Representations
Domain Modeling:

Domain Modeling | Concepts | Domain Definitions | Domain Operations | Domain Implementations | Systems | Case study: an Order processing system | Case study: an Airport Support system | Domain Orientation versus Object Orientation

Design Patterns:

Introduction | Abstract Factory | Builder | Factory Method | Prototype | Singleton | Adapter | Bridge | Composite | Decorator | Facade | Flyweight | Proxy | Chain of Responsibility | Command | Interpreter | Iterator | Mediator | Memento | Observer | State | Strategy | Template Method | Visitor 


click tracking


Send me your comments


This page was last modified on 04-12-2012 11:26:09   

free hit counter