Prototype design pattern in java - Java @ Desk

Tuesday, June 11, 2013

Prototype design pattern in java

Prototype pattern is used where the application needs many instances of an same object with minimal changes. Hence the Cloneable interface is used in this where the clone of the object is returned.

Question arises why clone, why not new object creation if many instances are required?

In general, cloning or creating an object using new operator are same. But there are cases where new object creation would be heavy in cases where a constructor for an object does some heavy provessing. Say for example, creating a database connection. In this case, cloning would be much much cheaper.

There is a case, where there are many fields in a class and those fields need to be initialized and then while execution few of the fields gets modified but other fields remain the same. So creating new object everytime would require setting of all fields everytime. Rather cloning would be beneficial and modify only those values that are required.

Consider an example, I need to generate Random number between two numbers, rangeStart and rangeEnd. But the rangeStart remains the same everytime. In this case, I will create a new object once and set the rangeStart value.

Later, I will clone the object and modify the rangeEnd value only.

RandomNumberGen.java
package com.designpatterns.prototype;

public interface RandomNumberGen {

    public void setRangeStart(int rangeStart);

    public void setRangeEnd(int rangeEnd);

    public void printRange();
}

RandomNumberGenImpl.java

package com.designpatterns.prototype;

package com.designpatterns.prototype;

import java.util.Random;

public class RandomNumberGenImpl implements RandomNumberGen, Cloneable {

    private int rangeStart;

    private int rangeEnd;
    
    public RandomNumberGenImpl(int rangeStart) {
        setRangeStart(rangeStart);
    }

    @Override
    public void setRangeStart(int rangeStart) {
        this.rangeStart = rangeStart;
    }

    @Override
    public void setRangeEnd(int rangeEnd) {
        this.rangeEnd = rangeEnd;
    }

    @Override
    public void printRange() {
        Random random = new Random();
        System.out.println("Random number between " + rangeStart + " and " + rangeEnd + " is : "
                + (random.nextInt(rangeEnd - rangeStart) + rangeStart));
    }

    @Override
    public RandomNumberGenImpl clone() throws CloneNotSupportedException {
        return (RandomNumberGenImpl) super.clone();
    }
}

PrototypeTest.java

package com.designpatterns.prototype;

import java.util.ArrayList;
import java.util.List;

public class PrototypeTest {

    public static void main(String args[]) throws CloneNotSupportedException {
        int rangeStart = 10;
        // Create a new object and pass rangeStart value
        RandomNumberGenImpl randomNumberGen = new RandomNumberGenImpl(rangeStart);
        
        List numberTwos = new ArrayList();
        numberTwos.add(50);
        numberTwos.add(60);
        numberTwos.add(70);
        numberTwos.add(80);
        numberTwos.add(90);

        for (int val = 0; val < numberTwos.size(); val++) {
            // Clone the object, so there is no need to set rangeStart value everytime
            RandomNumberGen numberGen = randomNumberGen.clone();
            numberGen.setRangeEnd(numberTwos.get(val));
            numberGen.printRange();
        }
    }
}








No comments:

Post a Comment