Where can I find good examples of the Prototype pattern?

Scott Stanchfield

The prototype pattern is actually quite simple to implement in Java.

Recall that the idea of prototype is that you are passed an object and use that object as a template to create a new object. Because you might not know the implementation details of the object, you cannot create a new instance of the object and copy all of its data. (Some of the data may not be accessible via methods). So you ask the object itself to give you a copy of itself.

Java provides a simple interface named Cloneable that provides an implementation of the Prototype pattern. If you have an object that is Cloneable, you can call its clone() method to create a new instance of the object with the same values.

The trick here is that you must override the clone() method to increase its visibility, and just call super.clone(). This is because the implementation of clone(), defined in java.lang.object, is protected. For example:

  public class CopyMe implements Cloneable {
    public Object clone() {
      return super.clone();

Note that Cloneable is an empty interface! It merely acts as a tag to state that you really want instance of the class to be cloned. If you don't implement Cloneable, the super.clone() implementation will throw a CloneNotSupportedException.

The Object implementation of clone() performs a shallow copy of the object in question. That is, it copies the values of the fields in the object, but not any actual objects that may be pointed to. In other words, the new object will point to the same objects the old object pointed to.

As an example of using the cloning:

  CopyMe thing = new Copyme();
  CopyMe anotherThing = 

This example is pretty trivial, but the real power comes when you don't know what you're actually cloning.

For example, suppose you define an interface that represents a customer:

  public interface Customer extends Cloneable {
    public Object clone(); // require making it public!
    public String getName();
    public void setName(String name);

You might have several different implementations of this interface, possibly storing data in a file, database, or using EJB Entity beans. If a shallow copy of the data is sufficient to represent a copy of the object, Java's clone() method works great.

You might have a method that needs to make a copy of the data to store it in a Hashtable, for example:

  public void storeCustomer(Customer customer) {
    Customer copy = (Customer)customer.clone();

Note that this method knows nothing about what type of customer we're getting. This pattern will work for any actual type of Customer, no matter how the data is stored. For example:

  FileBasedCustomer  c1 = new FileBasedCustomer(...);
  RDBMSBasedCustomer c2 = new RDBMSBasedCustomer(...);
  EJBBasedCustomer   c3 = new EJBBasedCustomer(...);