Как реализовать шаблон прототипа? - PullRequest
5 голосов
/ 20 августа 2010

Цель шаблона-прототипа - клонировать объект, уменьшив стоимость создания. Вот пример:

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();
   }
}

Я думаю, что это для глубокого копирования. Итак, кто-то может мне помочь в этом вопросе ???

Ответы [ 4 ]

1 голос
/ 20 августа 2010

Прежде всего, чтобы это работало, вашему классу Complex необходимо реализовать интерфейс маркера Cloneable , чтобы указать методу Object.clone (), что для этого метода допустимо создавать поле копия экземпляров этого класса. Затем вам нужно переопределить метод Object.clone (), чтобы указать поведение копирования:

public Complex clone(){
    Complex clone = (Complex)super.clone();
    clone.nums = this.nums;
    return clone;
}
0 голосов
/ 21 августа 2010

То, что вы говорите, отчасти верно в том смысле, что цель шаблона-прототипа - снизить стоимость создания объекта путем клонирования и избегания «нового».

Но это не значит, что вы можете использовать шаблон простоклонировать объекты.Существуют и другие важные соображения

  • Использование объекта-прототипа в качестве «создателя» всех других экземпляров.
  • Создание «почти» похожих экземпляров из данного экземпляра, прототип

Подводя итог, цель прототипа заключается в следующем:

  • Сокращение затрат на создание объектов путем клонирования «объекта-прототипа»
  • Когда объекты, созданные посредством прототипирования, будутнемного отличаться от объекта-прототипа.

Ниже приведен пример, в котором используется прототип экземпляра PageBanner для создания различных типов баннеров страниц, которые немного различаются

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

Да и в вашемслучай, пусть класс вашего объекта-прототипа реализует интерфейс маркера Cloneable

0 голосов
/ 20 августа 2010

Java-реализация для метода-клона не вызовет конструктор класса. он скопирует память, занятую текущим экземпляром, в другое место в памяти.

Таким образом, это действительно снижает стоимость создания нового объекта.

0 голосов
/ 20 августа 2010

Я не думаю, что приведенный пример реализован согласно шаблону прототипа.

Я вижу следующие ошибки:

  1. Интерфейс клонируемого маркера не реализован.
  2. новый экземпляр создается с помощью конструктора new Complex () в переопределенном методе клонирования.Такого не должно быть.Я имею в виду, что в шаблоне прототипа мы должны сделать копию исходного кода, внести некоторые изменения и использовать клон в соответствии с требованиями.Но не создавать новый экземпляр.Путем клонирования можно избежать затрат на создание экземпляра, но если мы переопределим метод клонирования и создадим его экземпляр самостоятельно, вы фактически увеличите его стоимость.

Некоторые ссылки для понимания шаблона прототипа:

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

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

...