Prototype design pattern

The prototype pattern is a creational design pattern in software development. It is used when the type of objects to create is determined by a prototypical instance, which is cloned to produce new objects. This pattern is used to: avoid subclasses of an object creator in the client application, like the factory method pattern does. Furthermore, it avoids the inherent cost of creating a new object in the standard way (e.g., using the 'new' keyword) when it is prohibitively expensive for a given application.

To implement the pattern, declare an abstract base class that specifies a pure virtual clone() method. Any class that needs a "polymorphic constructor" capability derives itself from the abstract base class, and implements the clone() operation..

[Wikipedia]

Intro

In this example we will create a Magician , Sniper and a Warrior. We want to clone them and get the same id's and content , while each one of them will be stored in his own memory location. 

Villain

public interface Villain extends Cloneable {
    // the class is Cloneable, which means it is ok to copy instances of this class
    public Villain clone();

    // for testing purposes , we want to know the hashcode
    public int getHashCode();
}

CloneFactory

public class CloneFactory {
    /*
    this factory receives a Villain or one of it's subclasses , makes a clone and stores it in the memory
     */
    public Villain getVillain(Villain villain){
        return villain.clone();
    }
}

Sniper

public class Sniper implements Villain {
    private int id;

    public Sniper(){
        this.id=(int)(100*Math.random());
    }
    @Override
    public Villain clone() {
        //calls Villain clone
        Sniper sniper=null;
        try {
            sniper=(Sniper) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return sniper;
    }
    public int getHashCode(){
        return System.identityHashCode(this);
    }
    public int getId(){
        return this.id;
    }
}

Magician

public class Magician implements Villain {
    private int id;

    public Magician(){
        this.id=(int)(100*Math.random());
    }

    @Override
    public Villain clone() {
        //calls Villain clone
        Magician magician=null;
        try {
            magician=(Magician) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return magician;
    }
    public int getHashCode(){
       return System.identityHashCode(this);
    }
    public int getId(){
        return this.id;
    }
}

Warrior

public class Warrior implements Villain {
    private int id;

    public Warrior(){
        this.id=(int)(100*Math.random());
    }

    @Override
    public Villain clone() {
        //calls Villain clone
        Warrior warrior=null;
        try {
            warrior=(Warrior) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return warrior;
    }
    @Override
    public int getHashCode() {
        return System.identityHashCode(this);
    }
    public int getId(){
        return this.id;
    }
}

Main

public class Main {
    /*
    We create a Magician, ,Sniper and a Warrior. We want to clone them and get the same id's and content , while 
    each one of them will be stored in his own memory location.
    */
    public static void main(String[]args){
        //creates CloneFactory
        CloneFactory cloneFactory = new CloneFactory();
        //Creates Magician
        Magician magician1 = new Magician();
        //Creates Sniper
        Sniper sniper1 = new Sniper();
        //Creates Warrior
        Warrior warrior1 = new Warrior();

        //creates clone
        Magician magician2 = (Magician) cloneFactory.getVillain(magician1);
        Sniper sniper2 = (Sniper) cloneFactory.getVillain(sniper1);
        Warrior warrior2 = (Warrior) cloneFactory.getVillain(warrior1);
        /*
        clones have the same content and stored in their own memory location,
        hence have a different hashCode
         */
        System.out.println("magician id: "+magician1.getId() +" clone id: "+magician2.getId());
        System.out.println("magician hashCode: "+magician1.getHashCode() +" clone hashCode: "+magician2.getHashCode());
        System.out.println("sniper id: "+sniper1.getId() +" clone id: "+sniper2.getId());
        System.out.println("sniper hashCode: "+sniper1.getHashCode() +" clone hashCode: "+sniper2.getHashCode());
        System.out.println("warrior id: "+warrior1.getId() +" clone id: "+warrior2.getId());
        System.out.println("warrior hashCode: "+warrior1.getHashCode() +" clone hashCode: "+warrior2.getHashCode());
    }
}

Running Example

magician id: 6 clone id: 6
magician hashCode: 1735600054 clone hashCode: 21685669
sniper id: 65 clone id: 65
sniper hashCode: 2133927002 clone hashCode: 1836019240
warrior id: 81 clone id: 81
warrior hashCode: 325040804 clone hashCode: 1173230247