Prototype Pattern in Java - the clone() method

A design pattern is simply a way of representing how software is written in a reproducible way. There are in fact different syntactical approaches to achieving the same thing.

So, the Prototype pattern is simply an approach that uses a master copy to implement some overriding functionality. There are several ways to do this in Java (as well, I believe in other languages). Here is one that uses the 'new' keyword, and it's based on using an interface as a contract with implementing concrete classes. Then a single method takes a concrete implementation of the interface and performs the same operation:

// software contract
interface Shape { 
   public void draw();
} 
// concrete implementations
class Line implements Shape {
   public void draw() {
      System.out.println("line");
   }
}
class Square implements Shape {
   public void draw() {
      System.out.println("square");
   }
}
...
class Painting {
   public static void main (String[] args) {
      Shape s1 = new Line ();
      Shape s2 = new Square ();
      ...
      paint (s1);
      paint (s2);
      ...
   }
   // single method executes against the software contract as a prototype
   static void paint (Shape s) {
      s.draw ();
   }
}

You can read more at http://www.javacamp.org/designPattern/prototype.html or check out the main Design Pattern site. The information is presented there complete with references.


The idea of prototype pattern is having a blueprint / template from which you can spawn your instance. It's not merely to "avoid using new in Java"

If you implement prototype pattern in Java, then yes by all means override the existing clone() method from Object class, no need to create a new one. (Also need implement Clonable interface or you'll get exception)

As an example:

// Student class implements Clonable
Student rookieStudentPrototype = new Student();
rookieStudentPrototype.setStatus("Rookie");
rookieStudentPrototype.setYear(1);

// By using prototype pattern here we don't need to re-set status and
// year, only the name. Status and year already copied by clone
Student tom = rookieStudentPrototype.clone();
tom.setName("Tom");

Student sarah = rookieStudentPrototype.clone();
sarah.setName("Sarah");

The example you've linked is correct and your code

return Tom.clone();

won't compile because clone() is not a static method.

Cloning is not about avoiding the use of new operator but creating a new instance that has the same state (values of its member fields) as that of the object that's being cloned. Hence, clone() is not static but an instance method so that you can create a new instance (and using new isn't a problem) that mirrors the state of the object that clone() has been invoked upon.

It's just that your example classes (like Tom) are so simple (with no state) that all that the clone() method is doing is to instantiate a new instance. If it had a bit more complex state (say an ArrayList of objects) the clone() method would have to do a deep copy of the ArrayList as well.

To elaborate with one of your example classes, assume that Tom had some instance state. Now, the clone() would also have to make sure that the copy being returned matches the state of the current one.

static class Tom implements Xyz {

    private String name;

    public Tom() {
      this.name = "Tom"; // some state
    }

    public Xyz clone()    {
      Tom t = new Tom();
      t.setName(getName()); // copy current state
      return t;
    }

   public String toString() {
      return getName();
    }

   public String getName() {
      return name;
    }

   public void setName(String name) {
      this.name = name;
    }
}