views:

80

answers:

4

The objective of prototype pattern is to clone an object by reducing the cost of creation. Here is an example:

class Complex {
    int[] nums = {1,2,3,4,5};
    public Complex clone() {
        return new Complex();//this line create a new object, so is it violate the objective             of prototype ?//
    }
}

class Test2 {
   Complex c1 = new Complex();
   Complex makeCopy() {
      return (Complex)c1.clone();// Is it actually create a new object ? based on the clone method in Complex class? //
   }
   public static void main(String[] args) {
       Test2 tp = new Test2();
       Complex c2 = tp.makeCopy();
   }
}

I think it is for deep copy. So, can someone help me on this question ???

+1  A: 

First of all, to get this working your Complex class needs to implement the Cloneable marker interface to indicate to the Object.clone() method that it is legal for that method to make a field-for-field copy of instances of that class. Then you need to override the Object.clone() method to specify the copy behaviour:

public Complex clone(){
    Complex clone = (Complex)super.clone();
    clone.nums = this.nums;
    return clone;
}
Jeroen Rosenberg
I thought the OP was asking about the theory behind the prototype pattern, no? And whether or not it actually instantiates new objects...
Kirk Woll
A: 

I don't think example given is implemented as per Prototype Pattern.

Mistakes I see are:

  1. Cloneable marker interface is not implemented.
  2. new instance is being created using "new Complex()" constructor in overridden clone method. This should not be the case. What I mean here is in prototype pattern we should make a copy of the source, make some changes and use clone according to the requirements. But not create new instance. By cloning cost of instance creation can be avoided, But if we override clone method and create instance of it self you are actually increasing cost of it.

Some links for understanding Prototype Pattern:

http://www.javabeat.net/tips/34-using-the-prototype-pattern-to-clone-objects.html

http://www.allapplabs.com/java_design_patterns/prototype_pattern.htm

YoK
A: 

java implementation for clone method won't call class constructor. it will copy memory occupied by current instance to another place in memory.

that's way its really reduce to cost of new object creation.

mohammad shamsi
A: 

What you are saying is partly correct in that the objective of prototype pattern is to reduce cost of creating an object by cloning and avoiding "new".

But that does not mean you can use the pattern just to clone objects. There are other important considerations

  • Use the prototype object as the "maker" of all other instances.
  • Create "almost" similar instances form a given instance, the prototype

To summarize, the prototype's objective is to:

  • Reduce the cost of creating objects, by cloning a "prototype object"
  • When objects created by prototyping will be slightly different from the prototypical object.

Below is an example that uses a prototypical PageBanner instance to create different types of page banners that vary slightly

 import java.awt.Dimension;
 import java.io.Serializable;

/**
 * This class also acts as a factory for creating prototypical objects.
 */
public class PageBanner implements Serializable, Cloneable  {
   private String slogan;
   private String image;
   private String font;
   private Dimension dimension;

   // have prototype banner from which to derive all other banners
   private static final PageBanner PROTOTYPE = new PageBanner("", 
       "blank.png", "Verdana", new Dimension(600, 45));

   PageBanner(String slogan, String image, String font, 
         Dimension dim)   {
      this.slogan = slogan;
      this.image = image;
      //... other assignments
   }

   // getters and setters..

   public String toString()   {
      return new StringBuilder("PageBanner[")
            .append("Slogan=").append(slogan)
            .append("Image=").append(image)
            .append("Font=").append(font)
            .append("Dimensions=").append(dimension)
            .toString();

   }

   protected Object clone()  {
      Object cln = null;
      try   {
         cln = super.clone();
      }catch(CloneNotSupportedException e)   {
         // ignore, will never happen
      }
      return cln;
   }

   /**
    * This is the creational method that uses the prototype banner 
    * to create banners and changes it slightly (setting slogan and image)
    */
   public static PageBanner createSloganBanner(String slogan, String image)   {
      PageBanner banner = (PageBanner) PROTOTYPE.clone();
      banner.slogan = slogan;
      banner.image = image;
      return banner;
   }

   /**
    * Another creational method that uses the prototype banner 
    * to create banners and changes it slightly (setting image)
    */
   public static PageBanner createImageBanner(String image)   {
      PageBanner banner = (PageBanner) PROTOTYPE.clone();
      banner.image = image;
      return banner;
   }

   // similarly you can have a number of creational methods with 
   // different parameters for different types of banners that 
   // vary slightly in their properties.

   // main... (for illustration)
   public static void main(String[] args) {
      // both these banners are created from same prototypical instance
      PageBanner slogan = PageBanner.createSloganBanner(
            "Stackoverflow Rocks", "stack.png");
      PageBanner img = PageBanner.createImageBanner("stackBanner.png");
   }
}

Oh and in your case, have your prototype object's class implement the Cloneable marker interface

naikus