在先前的工廠方法設計中,factory() 方法集中管理所有具體類型的建立邏輯。每當系統需要新增一種垃圾類型(如 Cardboard),就必須修改 factory() 的原始碼,違反開放封閉原則。為了解決這個問題,我們引入《設計模式》一書中的「原型模式」:將物件建立的資訊封裝在各個具體類別內部,並透過一個原型清單(掌控序列)來管理這些原型物件。
原型模式的基本思想是維護一組原型物件,每種型別對應一個。當需要建立新物件時,先根據輸入資訊(如類別名稱)在掌控序列中尋找匹配的原型,再呼叫其複製方法(本例中命名為 tClone())產生新實例。這樣,factory() 方法無需硬編碼任何建立細節,新增型別時只需繼承基礎類別並實作複製介面即可。
Java 1.1 的反射 API 提供了更優雅的解決方案:只要持有 Class 物件,即可動態呼叫建構子。程式將原型清單改為儲存 Class 物件的 Vector。factory() 方法遍歷清單,比對類別名稱;找到匹配項後,透過 getConstructor(double.class) 取得建構子,再以 newInstance() 建立實例。若清單中找不到,則嘗試以 Class.forName() 動態載入類別並加入清單,最後遞迴呼叫 factory() 重試。這種設計使 Trash 類別完全不需知道具體子類型,極大提升了擴充性。
Trash 抽象類別除基本欄位與 sumValue() 方法外,新增兩個內部例外類別(PrototypeNotFoundException、CannotCreateTrashException)以及靜態 Vector trashTypes 儲存原型。factory() 接受 Info 物件(封裝型別名稱與重量資料),執行上述反射建立流程。各子類別(Aluminum、Cardboard 等)只需提供單一 double 參數的建構子,其餘由反射自動處理。
垃圾資料從外部檔案(Trash.dat)讀取,格式為「完整類別名:重量」。ParseTrash.fillBin() 解析每一行,建立 Info 並呼叫 Trash.factory() 產生物件,最後放入容器。為支援不同集合類型,引入 Fillable 介面與 FillableVector 適配器,將 Vector 的 addElement() 映射為 addTrash(),展示適配器模式的應用。
範例 RecycleAP 仍使用 instanceof 進行分類,導致新增 Cardboard 時必須修改分類邏輯。這暴露 RTTI 最大的缺點:必須明確列舉所有型別。後續章節將示範如何透過訪問者模式等技術,將型別判斷邏輯封裝,實現真正的多型分派。