Search code examples
javadesign-patternsclonecloneableprototype-pattern

Prototype Pattern in Java - the clone() method


So, I've been reading on Design Patterns and the Prototype Patterns confuses me. I believe one of the points of using it is avoiding the need for using the new operator. Then I look at this example:

http://sourcemaking.com/design_patterns/prototype/java/1

First, Their idea of Prototype implements a clone() method, which is weird. Wikipedia also says I need a pure virtual method clone to be implemented by subclasses (why?). Doesn't Java already provide such a method, doing exactly what we need it to do (which is to create a copy of an object instead of instancing it from scratch)? Second, the clone method invokes the operator new! Surely the example is wrong? (In that case I should be studying Design Patterns elsewhere, heh?). Can someone tell if this correction makes it right?:

static class Tom implements Cloneable implements Xyz {
    public Xyz    cloan()    {
      return Tom.clone(); //instead of new I use clone() from Interface Cloneable
    }
    public String toString() {
      return "ttt";
    }
  } 

Any clarification is appreciated.


Solution

  • 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");