2010-08-20 60 views
5

原型模式的目标是通过降低创建成本来克隆对象。 这里是一个例子:如何实现原型模式?

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

我认为这是深层复制。那么,有人可以帮助我解决这个问题吗?

+0

我也查了维基百科对这种模式的定义。我同意这是没有意义的(类正在被实例化),除非你利用对象缓存。 – 2010-08-20 16:57:32

回答

1

首先,为了得到这个工作,Complex类需要实现Cloneable标记接口,以向Object.clone()方法指示该方法是合法的,以创建实例的字段对字段副本该类别。然后你需要重写Object.clone()方法来指定复制行为:

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

我以为OP在问原型模式背后的理论,不是吗?并且它是否实际实例化新对象... – 2010-08-20 17:05:32

0

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

错误我看到的是:

  1. Cloneable的标记接口未实现 。
  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

0

Java实现不会调用类的构造函数。 它会将当前实例占用的内存复制到内存中的另一个地方。

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

0

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

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

  • 使用原型对象作为所有其他实例的“制造者”。
  • 创建“差不多”相似的情况下形成一个给定的情况下,原型

总之,原型的目标是:

  • 减少创建对象的成本,通过克隆“的原型对象“
  • 通过原型创建的对象与原型对象略有不同时。

下面是使用原型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标记接口