首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 設計模式:Prototype (原型) 模式深度解析與實作

     編輯:Java 相關知識

模式定義與適用情境

Prototype 模式 透過複製現有原型物件來建立新物件,而非透過 new 實例化。適用於:

  • 類別在執行期才決定(如動態載入)。
  • 避免建立與產品類平行的工廠類階層。
  • 物件狀態組合有限,預先建立原型並複製比手動實例化更有效率。

核心角色

  1. Prototype (原型介面):宣告 clone() 方法,通常繼承 Cloneable。
  2. ConcretePrototype (具體原型):實作 clone(),執行淺層或深層複製。
  3. PrototypeManager (原型管理器):以登記表 (Registry) 管理原型,支援動態註冊、查找與自動載入。
  4. Client (客戶端):向管理器請求原型並呼叫 clone() 取得新實例。

完整程式碼實作

1. 原型介面

package meconsea;

import java.io.Serializable;

public interface IPrototypeRam extends Cloneable, Serializable {
    String getName();
    void setName(String name);
}

2. 具體原型

package meconsea;

public class PrototypeRam implements IPrototypeRam {
    private String name;

    public PrototypeRam() {
        this.name = "this is prototype!";
    }

    @Override
    public String getName() { return name; }

    @Override
    public void setName(String name) { this.name = name; }

    @Override
    public Object clone() {
        try {
            return super.clone(); // 淺層複製,String 為不可變故安全
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException("PrototypeRam not cloneable", e);
        }
    }
}

3. 原型管理器 (Singleton + Registry)

package meconsea;

import java.util.HashMap;

public class PrototypeManager {
    private static PrototypeManager instance;
    private final HashMap registry = new HashMap<>();

    private PrototypeManager() {}

    public static synchronized PrototypeManager getInstance() {
        if (instance == null) instance = new PrototypeManager();
        return instance;
    }

    public void register(String name, Object prototype) {
        registry.put(name, prototype);
    }

    public void unregister(String name) {
        registry.remove(name);
    }

    public Object getPrototype(String name) {
        Object proto = registry.get(name);
        if (proto == null) {
            try {
                // 動態載入並自動註冊
                proto = Class.forName(name).newInstance();
                register(name, proto);
            } catch (Exception e) {
                throw new RuntimeException("Prototype not found: " + name, e);
            }
        }
        return proto;
    }
}

4. 客戶端使用範例

package meconsea;

public class PrototypeClient {
    public static void main(String[] args) {
        PrototypeManager pm = PrototypeManager.getInstance();
        String className = "meconsea.PrototypeRam";

        // 取得原型 (首次會自動載入並註冊)
        PrototypeRam prototype = (PrototypeRam) pm.getPrototype(className);
        System.out.println("原型名稱:" + prototype.getName());

        // 複製 10 個實例並修改名稱
        for (int i = 0; i < 10; i++) {
            PrototypeRam clone = (PrototypeRam) prototype.clone();
            clone.setName(clone.getName() + i);
            System.out.printf("Clone %d: %s (原型不變: %s)%n", i, clone.getName(), prototype.getName());
        }
    }
}

關鍵設計考量

  • 淺層 vs 深層複製:若物件包含可變參考型別欄位,需覆寫 clone() 執行深層複製,或改用序列化/建構式複製。
  • 原型管理器:結合 Singleton 確保全域唯一登記表,支援執行期動態擴充新原型類別。
  • 效能優勢:避免重複昂貴的初始化邏輯(如資料庫查詢、複雜運算),直接複製已初始化物件。

小結

Prototype 模式以「複製」取代「建構」,配合原型管理器實現靈活的物件創建機制。掌握淺層/深層複製差異與動態註冊技巧,能有效解決執行期物件類型不確定或初始化成本高的問題。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved