2010-08-20 52 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標記接口