工廠模式雖封裝了創建邏輯,但每新增一種產品類型,就需新增對應的工廠類別,導致平行階層膨脹。原型模式(Prototype Pattern)另闢蹊徑:用原型實例指定創建物件的種類,並透過拷貝這些原型創建新物件(GoF)。它不問「怎麼構建」,只問「複製哪個」,極適合「產品類型動態、大量相似實例」的場景。
.NET 提供兩種原生拷貝機制:
| 特性 | 淺拷貝 | 深拷貝 |
|---|---|---|
| 方法 | Object.MemberwiseClone() | 序列化反序列化 / 手動遞迴複製 |
| 值型別 | 逐位複製 | 逐位複製 |
| 參考型別 | 複製參考(共用同一物件) | 遞迴複製被參考物件 |
| 效能 | 極快 | 較慢(序列化開銷) |
| 適用場景 | 純值型別欄位、不可變物件 | 包含可變參考型別欄位 |
每種顏色一個類別 + 一個工廠類別。顏色數量動態增減時,類別爆炸。

關鍵設計:單一 ConcreteColorPrototype 類別以參數化 RGB 值表示所有顏色,透過 Clone() 複製。
[Serializable]
public abstract class ColorPrototype {
public abstract ColorPrototype Clone(bool deep);
}
[Serializable]
public class ConcreteColorPrototype : ColorPrototype {
private int _red, _green, _blue;
public ConcreteColorPrototype(int r, int g, int b) { _red = r; _green = g; _blue = b; }
public override ColorPrototype Clone(bool deep) {
return deep ? CreateDeepCopy() : (ColorPrototype)MemberwiseClone();
}
// 深拷貝實現
private ColorPrototype CreateDeepCopy() {
using (var ms = new MemoryStream()) {
var formatter = new BinaryFormatter();
formatter.Serialize(ms, this);
ms.Position = 0;
return (ColorPrototype)formatter.Deserialize(ms);
}
}
public void Display(string name) =>
Console.WriteLine($"{name}'s RGB Values are: {_red},{_green},{_blue}");
}
public class ColorManager {
private readonly Hashtable _prototypes = new Hashtable();
public ColorPrototype this[string name] {
get => (ColorPrototype)_prototypes[name];
set => _prototypes.Add(name, value);
}
}

class App {
public static void Main() {
var manager = new ColorManager();
// 初始化基礎原型(可從配置檔、資料庫載入)
manager["red"] = new ConcreteColorPrototype(255, 0, 0);
manager["green"] = new ConcreteColorPrototype(0, 255, 0);
manager["blue"] = new ConcreteColorPrototype(0, 0, 255);
// 動態新增語義化顏色(無需新增類別!)
manager["angry"] = new ConcreteColorPrototype(255, 54, 0);
manager["peace"] = new ConcreteColorPrototype(128, 211, 128);
manager["flame"] = new ConcreteColorPrototype(211, 34, 20);
// 使用:複製原型而非 new
var c1 = (ConcreteColorPrototype)manager["red"].Clone(false);
c1.Display("red");
var c2 = (ConcreteColorPrototype)manager["peace"].Clone(true); // 深拷貝
c2.Display("peace");
}
}
ColorFactory、RedFactory 等,直接複製原型ColorPrototype,具體原型亦依賴抽象
ICloneable 介面:標準化克隆契約(雖因淺/深拷貝語義模糊被部分指南不推薦)DataTable.Clone() / Copy():複製結構 vs 複製結構+資料Expression 樹的 Visit 模式:本質是原型式的樹結構複製與修改Instantiate(prefab):Unity 的 Prefab 系統即原型模式經典應用List<T>、自訂類別欄位時,複製出的實例共用子物件,修改一方影響另一方 → 必須深拷貝或實作 ICloneable 時手動複製集合[Serializable];不支援委派、事件、非序列化欄位;效能較差 → 高效能場景考慮 Expression 樹編譯複製或手寫複製邏輯ConcurrentDictionaryDictionary 追蹤已複製物件以下情況優先考慮原型模式:
原型模式以「複製」取代「構建」,將創建知識從「如何一步步建構」轉移為「複製哪個範本」。它不解決「建構複雜物件」的問題(那是建造者的事),而是解決「大量相似、動態類型、避免工廠膨脹」的問題。在 .NET 中,配合序列化或 MemberwiseClone,原型模式是實現物件模板、預設值管理、運行期類型擴展的利器。記住:當你發現自己在寫大量「參數化建構子」或「工廠方法只是單純 new 不同參數」時,原型模式可能是更好的選擇。