Putting the Prototype Pattern to Work

Wednesday May 31st 2000 by Wiebe deJong

Here we put Prototype to practical use in developing symbol libraries for a CAD program API.

Back in my C++ days, when I wrote CAD (computer aided drafting) programs, one of the more trying tasks was to write an API, a program that allowed third parties to offer symbol libraries of their products. Supposedly, they would sell more products if the clients used them in their drawings.

Unfortunately, the API ended up being cumbersome and difficult to use; in fact, I was the only one who used it to implement libraries. If I had known how to develop symbol libraries with the Prototype pattern, the projects would have been much simpler and more successful.

This tutorial builds upon Mark Grand's work. In his article, he describes the Prototype design pattern and Java-related issues like cloning. I will be presenting an implementation of the pattern that builds on his work.

The Prototype Pattern

Start with an interface for each object. As shown in Listing 1, the interface is used to extend the Cloneable and Serializable interfaces. The Prototype pattern requires the ability to be cloned. Serialization is needed to implement objects in files.

Listing 1. CadSymbolIF.java

// CadSymbolIF - symbol library interface

import java.awt.*;

import java.io.*;

public interface CadSymbolIF extends Cloneable, Serializable {


  public String getName();

  public void setName(String name);

  public String getType();


  // some example method needed by the cad program

  public Dimension getExtents ();

  public void setExtents (Dimension d);

  public Dimension getOrigin ();

  public void setOrigin (Dimension d);

  public void draw (Graphics g);



In order for the symbols to be read from a file, or stream, they must support serialization. Simply stated, object serialization provides a program with the ability to read or write objects from a stream. In our example, this stream comes from a file and a filter, in the form of ObjectInputStream(). ObjectInputStream is applied to the stream to convert it into a series of objects.

Any object that needs to be serialized must implement the Serializable interface. Since this interface has no methods, making something serializable is as simple as adding the "implements Serializable" clause to the class definition.

If there are special requirements, say, the objects require special storage, an object could alternately implement the Externalizable interface. The interface has two methods, readExternal() and writeExternal(). Both of these methods give the developer complete control over the serialization and re-constitution process; the developer can choose to encrypt the objects, for example, or, perform error-checking and/or compression.


The interface in Listing 1 contains definitions of some basic methods required by the CAD program. For example, every object will need to know where it is and how to draw itself. You may add as many methods as you need.

The actual objects

The CadSymbolIF interface is implemented by abstract class CadSymbol (see Listing 2), the base object. This class will contain the code common to all the CAD symbols.

Listing 2. CadSymbol.java

// CadSymbol - abstract base class

import java.awt.*;

import java.io.*;

public abstract class CadSymbol implements CadSymbolIF {

  // methods for Cloneable interface

  public Object clone() {

    try {

      return super.clone();

    } catch (CloneNotSupportedException e) {

      // This should never happen because this class implements Cloneable

      throw new InternalError();




  // methods for Serializable interface, if needed

//  private void writeObject(java.io.ObjectOutputStream out) throws IOException

//  private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException; 


  // identity methods

  private String name;

  public String getName() {

    return name; 


  public void setName(String name) {

    this.name = name;


  abstract public String getType();


  // some example method needed by the cad program

  protected Dimension extents, origin;

  public Dimension getExtents () {

    return extents;


  public void setExtents (Dimension d) {

    extents = d;


  public Dimension getOrigin () {

    return origin;


  public void setOrigin (Dimension d) {

    origin = d;


  abstract public void draw (Graphics g);


The getType() function is declared abstract in order to force the developer to create one for each CAD symbol, based on the abstract class. The function should return a unique identifier string that the application can associate with the symbol.

An example symbol is presented in Listing 3. The getType() method has been implemented with a string unique to this symbol.

Listing 3. BasicUnit.java

// BasicUnit - an example of CadSymbol

import java.awt.*;

public class BasicUnit extends CadSymbol {

  public void draw (Graphics g) {

    // draw self


  public String getType() { return "BasicUnit"; }


Loading the symbols

The CAD symbols are made available to the application in a serialized form in a file. The file must to be read into the application and the objects within it must be reconstituted. The CadSymbolManager, shown in Listing 4, stores the prototype objects in a vector using the type identifier of the object as the key. Supplying its identifier to the Manager via the getSymbol() method will allow it to retrieve an object.

Listing 4. CadSymbolManager.java

// CadSymbolManager

import java.util.*;

public class CadSymbolManager {

  private Vector symbols = new Vector();


  // add symbol to collection

  void addSymbol(CadSymbol sym) {

    symbols.put(sym.getType(), sym);



  // retrieve symbol by type

  CadSymbol getSymbol (String symbolType) {

    return (CadSymbol) ((CadSymbol)symbols.get(symbolType)).clone();




CadSymbolLoader, as shown in Listing 5, performs the actual reconstitution of the symbols. The sole function of this class is to load symbols from a library file and add them to the Manager. To simplify the code, no end-of-file (EOF) check is done. The loop will continue to read until an attempt is made to read past the EOF marker. When this occurs, an exception is raised and the loop terminates.

Listing 5. CadSymbolLoader.java

// CadSymbolLoader

import java.util.*;

public class CadSymbolLoader {

  private CadSymbolManager mgr;


  // constructor

  CadSymbolLoader (CadSymbolManager csm) {

    mgr = csm;



  // load symbol libary

  int loadCadSymbols (String fname) {

    int symbolCount = 0;


    try {

      InputStream in;

      in = new FileInputStream(fname);

      in = new BufferedInputStream(in);

      ObjectInputStream oIn = new ObjectInputStream(in);

      while (true) { // loop until end of file

        Object c = oIn.readObject();

        if (c instanceOf CadSymbol) {





    } catch (Exception e) {

      // do nothing



    return symbolCount;



Graphical Palettes

Graphical symbol palettes (little windows with clickable images in them), can be implemented by adding a getPaletteIcon() function to the CadSymbolIF interface. The function returns a small icon (.bmp, .gif, or whatever) representative of the symbol. Adding an iterator to the CadSymbolManager allows the CAD program to determine the icon and type of every symbol in a library. These symbols can then be used to construct the palette.

When the user clicks on a particular icon in the palette, the associated type will retrieve a symbol from the CadSymbolManager using the getSymbol() method.

Dynamic libraries

Using ObjectOutputStream to serialize the objects opens up some interesting possibilities for dynamic libraries. Instead of being read from the same static file every time, libraries could be supplied on a CD-ROM that, with a subscription, is updated periodically by the product distributor. The libraries could also be read directly from a manufacturer's Web site during program startup (via RMI, for example), allowing for highly customized and timely components.


To make symbol libraries easy to locate and access, a properties file can be used to store the file name and location information. If the file is read from a Web site, the corresponding URL would be stored here. Any additional information, like a title for the palette, can also be stored here. The properties files can be used to implement multiple symbol libraries. A code to process multiple files would begin something like this:

Listing 6. Example

CadSymbolManager csm = new CadSymbolManager();
CadSymbolLoader csl = new CadSymbolLoader(csm);
while ( /* read fname from properties */ ) {
This example shows all symbols being loaded into one Manager. You could also choose to have a separate Manager for each library, or even each palette.


The use of an established design pattern makes implementation much easier for the developer. Instead of coming up with a solution on your own, it is reassuring to have a solution that has been discussed, proofed, and streamlined. If I had known about the Prototype pattern 10 years ago, my job would have been much simpler.

About the Author

With over thirteen years' experience in application development, Wiebe de Jong is a Web developer for IMRglobal Ltd. in Vancouver, BC, Canada. He develops Internet and intranet applications for clients using Java, UML, and XML. He also teaches.

Mobile Site | Full Site
Copyright 2017 © QuinStreet Inc. All Rights Reserved