乍看之下,new ClassName() 似乎已足夠創建物件。但當系統面臨「創建邏輯複雜」、「具體類別頻繁變化」、「需要統一生命週期管理」等挑戰時,直接實例化將導致客戶端程式碼瀰漫著具體類別名稱、建構參數、初始化邏輯。創建型模式的核心價值在於:封裝「什麼時候創建什麼物件、由誰創建、如何創建」的變化點,讓客戶端僅依賴抽象介面。
| 模式 | 核心解決問題 | 關鍵詞 | 變化維度 |
|---|---|---|---|
| 單例 | 確保類別全域唯一實例 | 實例控制、全域存取 | 實例數量 |
| 工廠方法 | 延遲實例化到子類別 | 單一產品、平行階層 | 單一物件類型 |
| 抽象工廠 | 創建相關/相依物件族群 | 產品族、系列對象 | 系列對象組合 |
| 建造者 | 分步驟構建複雜物件 | 構建算法、部件組裝 | 物件內部結構 |
| 原型 | 透過複製現有實例創建新物件 | 克隆、動態原型管理 | 易變物件類型 |
假設遊戲場景需構建「房屋」,包含牆、門、房間等部件,風格分「現代」、「古典」。
場景:遊戲規定每棟房屋僅能有一扇大門。
public sealed class SingletonDoor {
private static readonly SingletonDoor _instance = new SingletonDoor();
private SingletonDoor() { } // 私有建構子
public static SingletonDoor Instance => _instance;
}

解決:實體物件個數控制問題。
場景:牆有現代/古典風格,客戶端不想直接 new ModernWall()。
public abstract class Wall { public abstract void Display(); }
public class ModernWall : Wall { public override void Display() => Console.WriteLine("ModernWall"); }
public class ClassicalWall : Wall { public override void Display() => Console.WriteLine("ClassicalWall"); }
public abstract class WallFactory { public abstract Wall Create(); }
public class ModernWallFactory : WallFactory { public override Wall Create() => new ModernWall(); }
public class ClassicalWallFactory : WallFactory { public override Wall Create() => new ClassicalWall(); }

解決:單一物件類型的需求變化。客戶端僅依賴 WallFactory,切換風格只需替換工廠實例。
場景:房屋包含牆、房間、門,現代風格的房屋必須用現代牆、現代房間、現代門,不可混搭。
public abstract class AbstractFactory {
public abstract Wall CreateWall();
public abstract Room CreateRoom();
public abstract Door CreateDoor();
}
public class ModernFactory : AbstractFactory {
public override Wall CreateWall() => new ModernWall();
public override Room CreateRoom() => new ModernRoom();
public override Door CreateDoor() => new ModernDoor();
}
public class ClassicalFactory : AbstractFactory { /* 古典系列實作 */ }

解決:系列物件的一致性創建。確保同風格部件協同工作,避免「現代牆配古典門」的邏輯錯誤。
場景:場景構建步驟固定(先蓋牆、再蓋房、最後裝門),但每步驟的具體部件隨風格變化。
public class Director {
public void Construct(Builder builder) {
builder.BuildWall(); // 步驟 1
builder.BuildRoom(); // 步驟 2
builder.BuildDoor(); // 步驟 3(算法固定)
}
}
public abstract class Builder {
public abstract void BuildWall();
public abstract void BuildRoom();
public abstract void BuildDoor();
public abstract GameScene GetResult();
}
public class ModernBuilder : Builder { /* 現代部件實作 */ }
public class ClassicalBuilder : Builder { /* 古典部件實作 */ }

解決:物件部分構建的變化。Director 掌控算法,Builder 實作細節,兩者獨立演化。
場景:遊戲地圖需大量相同風格的牆、房間,逐個 new 成本高、參數配置繁瑣。
public abstract class RoomPrototype {
public abstract RoomPrototype Clone();
}
public class ModernRoomPrototype : RoomPrototype {
public override RoomPrototype Clone() => (RoomPrototype)this.MemberwiseClone(); // 淺拷貝
// 或序列化實現深拷貝
}
public class ClassicalRoomPrototype : RoomPrototype { /* ... */ }

解決:易變物件類型的創建。原型管理器動態註冊/移除原型,客戶端透過 Clone() 獲取新實例。
實務上,模式常組合使用:抽象工廠內部用工廠方法創建產品;建造者回傳的產品可能是原型的複製品;單例常作為工廠/建造者/原型管理器的全域存取點。
HttpContext.Current、ConfigurationManager、Trace.ListenersWebRequest.Create()、SymmetricAlgorithm.Create()、DbProviderFactoryDbProviderFactory(連線、命令、參數、適配器全套)、IServiceProviderStringBuilder、UriBuilder、DbConnectionStringBuilder、Expression 樹建構ICloneable、MemberwiseClone()、序列化深拷貝、DataTable.Clone()創建型模式不是為了「創建物件」——new 就能辦到;而是為了管理創建的複雜性、封裝創建的變化、解耦客戶端與具體類別。掌握五大模式的適用邊界與組合技巧,是從「會寫程式」進階到「會設計系統」的關鍵門檻。記住:沒有最好的模式,只有最適合當前變化維度的模式。