Skip to content
Related Articles

Related Articles

Improve Article
Save Article
Like Article

Java Pattern Prototype on Game Server

  • Difficulty Level : Easy
  • Last Updated : 18 Jan, 2022

Sometimes also known as cloning, basically the prototype is a generative design pattern that allows you to copy objects without making your code dependent on their classes.


The idea is to create a pack of monsters that will attack our hero/character. A specific configuration is set for enemies – Enemy config. With the help of the prototype, we will be able to copy the basic enemies and make groups of them. We can also copy groups and make up large units of them. We can set parameters, for example, 20 melee enemies and 40 ranged enemies. Based on the basic configuration, we can create copies of the units. That will further allow us to clone entire units. Cool, isn’t it?


Let’s say you have an Enemy object and you want to create an exact copy of it. How would you do it? First, we need to create a new object of the same class. Then you need to go through all the fields of the original object and copy their values to the new object.

Fine! But there is a catch. Not all objects can be copied in this way because some fields may be closed and not visible from outside the object itself.

There is another problem with the direct approach. Since we need to know the object’s class to create a duplicate, our code becomes dependent on that class. If other addiction doesn’t scare us, there is another snag. Sometimes you only know the interface that an object follows, but not its specific class, when, for example, a parameter in a method accepts any objects that follow some interface.


The Prototype template delegates the cloning process to natural cloned objects. The template declares a standard interface for all objects that support cloning. This interface allows you to clone an object without binding any code to the class of that object. Usually, such an interface contains only one clone method.

The implementation of the clone method in all classes is very similar. The method creates an object of the current class and transfers all the field values of the old object to the new one. You can even copy private fields because most programming languages allow objects to access the private fields of other objects belonging to the same class.

An object that supports cloning is called a prototype. When your objects have dozens of fields and hundreds of possible configurations, cloning them can be an alternative to subclassing.

Here’s how it works: you create a set of objects that are customizable in various ways. When you need an object like the one you customized, you clone the prototype instead of creating a new object from scratch.


 Use the prototype pattern when your code does not need to depend on the specific classes of objects that you need to copy.

This often happens when your code works with objects passed to you from third-party code through some interface. The specific classes of these objects are unknown, and you could not depend on them even if you wanted to.

The prototype template provides a common interface for client code to work with all objects that support cloning. This interface makes the client code independent of the specific classes of cloned objects.

The Prototype pattern allows you to use a set of pre-created objects, configured in various ways as prototypes.

Instead of instantiating a subclass to match some configuration, the client can find the appropriate prototype and clone it.

How to implement

Create a prototype interface and declare a clone method in it. Or add a method to all classes of the existing class hierarchy if you have one.

The prototype class must define an alternative constructor that takes an object of that class as an argument. The constructor must copy the values ​​of all fields defined in the class from the passed object to the newly created instance. If you change the subclass, you must call the parent constructor to let the superclass handle cloning of its private fields. If your programming language does not support method overloading, you can define a special method to copy object data. The constructor is a more convenient place because it delivers the resulting object immediately after the call to the new operator.

The cloning method usually consists of one line: starting a new statement with a prototype constructor. Note that each class must explicitly override the clone method and use its class name along with the new operator. Otherwise, the clone method can create an object of the parent class.

Optionally, you can create a centralized prototype registry to store a catalog of frequently used prototypes. Using a static prototype fetch method, you can implement the registry as a new factory class or place it in the prototype base class. This method should search for a prototype based on the search criteria that the client code passes to the method. The requirements can be either a simple string tag or a complex set of search parameters. Once a matching prototype is found, the registry must clone it and return it to the client. Finally, replace direct calls to subclass constructors with calls to the prototype registry factory method.

Copying enemies

Let’s see how you can implement a prototype without the standard Cloneable interface.

Step 1: Let’s create a basic abstract class Enemy

Example 1:


// Java Program to Create Abstract Enemy class
// Abstract class
public abstract class Enemy {
  // enemy health
   public int health;
   // enemy speed
   public int speed;
   // enemy name
   public String name;
   // Constructor 1
   // Base constructor
   public Enemy() {
   // Constructor 2
   // Copy constructor
   public Enemy(Enemy target) { 
      // Check that target not empty
       if (target != null) {          
          // set base params and note
           // this keyword refers to current instance itself
           this.speed = target.speed;
   // clone() method
   public abstract Enemy clone();
   // Override equals() method
   public boolean equals(Object o) {
       if (!(o instanceof Enemy)) return false;
       Enemy enemy = (Enemy) o;
       return == health && enemy.speed == speed && Objects.equals(, name);
  // Override hashCode() method
   public int hashCode() {
       return Objects.hash(health, speed, name);

Step 2: We need several enemies. Let it be ArcherEnemy and MeleeEnemy

Example 2-A


// Let`s create ArcherEnemy with attack range
public class ArcherEnemy extends Enemy { // Enemy is a parent
   public int attackRange; // add new param
   public ArcherEnemy() {
   public ArcherEnemy(ArcherEnemy target) { // clone constructor
       super(target); // first of all clone base Enemy
       if (target != null) {
           this.attackRange = target.attackRange; // then clone additional params
    Clone based on THIS enemy
   public Enemy clone() {
       return new ArcherEnemy(this);
   public boolean equals(Object o) {
       if (this == o) return true;
       if (o == null || getClass() != o.getClass()) return false;
       if (!super.equals(o)) return false;
       ArcherEnemy that = (ArcherEnemy) o;
       return attackRange == that.attackRange ;
   public int hashCode() {
       return Objects.hash(super.hashCode(), attackRange);

Example 2-B


// Let`s create MeleeEnemy with 'melee params'
public class MeleeEnemy extends Enemy {
    public int blockChance; // add new param
    public boolean withShield; // add new param
    public MeleeEnemy() {}
    // Create clone constructor
    // clone base Enemy
    // and then clone additional params
    public MeleeEnemy(MeleeEnemy target)
        if (target != null) {
            this.blockChance = target.blockChance;
            this.withShield = target.withShield;
    //  Clone class based on current values
    @Override public Enemy clone()
        return new MeleeEnemy(this);
    @Override public boolean equals(Object o)
        if (this == o)
            return true;
        if (o == null || getClass() != o.getClass())
            return false;
        if (!super.equals(o))
            return false;
        MeleeEnemy that = (MeleeEnemy)o;
        return blockChance == that.blockChance
            && withShield == that.withShield;
    @Override public int hashCode()
        return Objects.hash(super.hashCode(), blockChance,

  Step 3: Let’s test the creation of clones as we have basic enemies ready.

Example 3:


// Java Program to Illustrate Creation of Clones
// Main class
public class Demo {
    // Method 2
    // Main driver method
    public static void main(String[] args)
        // Creating enemy list
        List<Enemy> enemyList = new ArrayList<>();
        // Creating enemy list copy
        List<Enemy> enemyListCopy = new ArrayList<>();
        // Create baseArcher
        ArcherEnemy baseArcher = new ArcherEnemy();
        // Setting attributes = 150;
        baseArcher.speed = 35; = "Base Archer";
        baseArcher.attackRange = 100;
        // Create clone baseArcher
        ArcherEnemy baseArcherClone
            = (ArcherEnemy)baseArcher.clone();
        // Adding clone to enemyList
        // Create baseMeleeEnemy
        MeleeEnemy baseMeleeEnemy = new MeleeEnemy();
        // Setting attributes = 10;
        baseMeleeEnemy.speed = 20; = "blue";
        baseMeleeEnemy.blockChance = 7;
        baseMeleeEnemy.withShield = true;
        // Now adding baseMeleeEnemy to enemyList
        // using add() method
        // Cloning whole list and comparing
        cloneAndCompare(enemyList, enemyListCopy);
    // Method 1
    // To clone and compare
    private static void
    cloneAndCompare(List<Enemy> enemyList,
                    List<Enemy> enemyListCopy)
        // Iterate over enemyList
        // using for-each loop
        for (Enemy enemy : enemyList) {
            // Clone enemys and add into enemyListCopy
        // Compare enemys in enemyList and in enemyListCopy
        for (int i = 0; i < enemyList.size(); i++) {
            // Checking that enemy and cloneEnemy have
            // different links
            if (enemyList.get(i) != enemyListCopy.get(i)) {
                // Simply printing the result
                    + ": Enemy are different objects (yay!)");
                // Check that they have same params
                if (enemyList.get(i).equals(
                        enemyListCopy.get(i))) {
                    // Print statement if they are identical
                        + ": And they are identical (yay!)");
                else { // Print statement if they are
                       // not-identical
                        + ": But they are not identical (booo!)");
            else {
                // Print statement if Shape objects are same
                    + ": Shape objects are the same (booo!)");


0: Enemy are different objects (yay!) // have different links
0: And they are identical (yay!)      // but have same inner state
1: Enemy are different objects (yay!) // have different links
1: And they are identical (yay!)      // but have same inner state
2: Enemy are different objects (yay!) // have different links
2: And they are identical (yay!)      // but have same inner state

We got a list of enemies that we can copy and transfer to the client, if necessary. With this approach, we have the opportunity to use already created enemies and combine them into different groups, storing them in complex data structures. 

My Personal Notes arrow_drop_up
Recommended Articles
Page :

Start Your Coding Journey Now!