Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何实现原型模式?_Java_Design Patterns_Prototype Pattern - Fatal编程技术网

Java 如何实现原型模式?

Java 如何实现原型模式?,java,design-patterns,prototype-pattern,Java,Design Patterns,Prototype Pattern,原型模式的目标是通过降低创建成本来克隆对象。 以下是一个例子: 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

原型模式的目标是通过降低创建成本来克隆对象。 以下是一个例子:

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

我认为这是深度复制。那么,有人能帮我解决这个问题吗?

首先,要让这个复杂的类工作,你需要实现marker接口,向Object.clone()方法表明,该方法为该类的实例创建一个字段对字段的副本是合法的。然后需要重写Object.clone()方法以指定复制行为:

public Complex clone(){
    Complex clone = (Complex)super.clone();
    clone.nums = this.nums;
    return clone;
}

我不认为给出的示例是按照原型模式实现的

我看到的错误是:

  • 可克隆标记接口不可用 执行
  • 正在使用创建新实例 重写的克隆方法中的“new Complex()”构造函数。这 不应该是这样。我的意思是 这是我们应该复制的原型模式 源代码,进行一些更改并 根据需要使用克隆。但不创建新实例。通过克隆可以避免实例创建的成本,但若我们重写克隆方法并自行创建实例,那个么实际上是在增加它的成本
  • 了解原型模式的一些链接:


    克隆方法的java实现不会调用类构造函数。 它将当前实例占用的内存复制到内存中的另一个位置


    这才是真正降低新对象创建成本的方法。

    您所说的部分正确,因为原型模式的目标是降低成本 通过克隆和避免“新建”来创建对象

    但这并不意味着您可以仅使用模式来克隆对象。还有其他重要的考虑因素

    • 将原型对象用作所有其他实例的“制造者”
    • 创建“几乎”相似的实例形成一个给定的实例,原型
    总之,原型的目标是:

    • 通过克隆“原型对象”降低创建对象的成本
    • 当原型创建的对象与原型对象略有不同时
    下面是一个使用原型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
    marker接口

    我也检查了维基百科对这个模式的定义。我同意,除非你利用对象缓存,否则这毫无意义(类正在以任何方式实例化)。我以为OP是在询问原型模式背后的理论,不是吗?不管它是否真的实例化了新对象。。。