設計模式:建立型—原型模式

語言: CN / TW / HK

原型模式的定義

如果物件的建立成本比較大,而同一個類的不同物件之間差別不大(大部分欄位都相同),在這種情況下,我們可以利用對已有物件(原型)進行復制(或者叫拷貝)的方式來建立新物件,以達到節省建立時間的目的。

這種基於原型來建立物件的方式就叫作 原型設計模式(Prototype Design Pattern) ,簡稱 原型模式。

理解物件的建立成本

實際上,建立物件包含的申請記憶體、給成員變數賦值這一過程,本身並不會花費太多時間,或者說對於大部分業務系統來說,這點時間完全是可以忽略的。

但是,如果物件中的資料 需要經過複雜的計算 才能得到(比如排序、計算雜湊值),或者需要從 RPC、網路、資料庫、檔案系統等非常慢速的 IO 中讀取,這種情況下,我們就可以利用原型模式,從其他已有物件中直接拷貝得到,而不用每次在建立新物件的時候,都重複執行這些耗時的操作。

原型模式的實現方式:深拷貝和淺拷貝

在 Java 語言中,Object 類的 clone() 方法執行的就是我們常說的淺拷貝。它只會拷貝物件中的基本資料型別的資料(比如,int、long),以及引用物件(SearchWord)的記憶體地址,不會遞迴地拷貝引用物件本身。

那如何實現深拷貝呢?

第一種方法:遞迴拷貝物件、物件的引用物件以及引用物件的引用物件……直到要拷貝的物件只包含基本資料型別資料,沒有引用物件為止。

第二種方法:先將物件序列化,然後再反序列化成新的物件。

原型模式Java 實現

下面Java實現程式碼轉自 維基百科

/** Prototype Class **/
public class Cookie implements Cloneable {
   
    public Object clone() throws CloneNotSupportedException
    {
        //In an actual implementation of this pattern you would now attach references to
        //the expensive to produce parts from the copies that are held inside the prototype.
        return (Cookie) super.clone();
    }
 }
 
 /** Concrete Prototypes to clone **/
 public class CoconutCookie extends Cookie { }
 
 /** Client Class**/
 public class CookieMachine
 {
 
   private Cookie cookie;//cookie必須是可複製的
 
     public CookieMachine(Cookie cookie) { 
         this.cookie = cookie; 
     } 

    public Cookie makeCookie()
    {
        try
        {
            return (Cookie) cookie.clone();
        } catch (CloneNotSupportedException e)
        {
            e.printStackTrace();
        }
        return null;
    } 

 
     public static void main(String args[]){ 
         Cookie tempCookie =  null; 
         Cookie prot = new CoconutCookie(); 
         CookieMachine cm = new CookieMachine(prot); //設定原型
         for(int i=0; i<100; i++) 
             tempCookie = cm.makeCookie();//通過複製原型返回多個cookie 
     } 
 }

原型模式的優缺點

優點

  • 複雜物件建立更快
  • 逃避掉了建構函式的約束(建構函式不會執行)

缺點

  • 必須實現 Cloneable 介面
  • 建構函式不會執行