2026年10月20日 星期二

有 Creational Patterns 的原因,是否是有些狀況不適合直接用 new 建造出一個物件來用?

 沒錯!您的直覺非常準確,這正是整個創建型模式(Creational Patterns)核心要解決的根本問題。


在軟體開發中,直接使用 new 關鍵字來建立物件(例如 MyClass obj = new MyClass();)雖然直覺又方便,但在中大型系統或需要高度擴充性的架構中,直接使用 new 會帶來幾個致命的痛點。創建型模式的存在,就是為了將「物件的建立邏輯」與「物件的使用方式」徹底解耦。

直接使用 new 會遇到以下幾種不適合的狀況:


1. 緊密耦合(Tight Coupling)與無法抽換實作

當你在程式碼各處直接 new SpecificClass() 時,你的程式碼就和這個具體類別(Concrete Class)綁死了。

  • 問題: 如果有一天業務需求改變,需要將 MySQLDatabase 改成 PostgreSQLDatabase,或者需要換成用於單元測試的 MockDatabase,你就必須去修改所有出現 new MySQLDatabase() 的地方。

  • 解法: 透過 Factory 或是依賴注入(Dependency Injection),讓程式碼只依賴介面(Interface),由工廠在背後決定要 new 哪個具體物件。

2. 物件建立過程極為繁複(Complex Initialization)

有些物件的誕生不是單純呼叫無參數建構子就能搞定的,它可能需要:

  • 依序讀取設定檔、連線資料庫、初始化緩衝區。

  • 傳入一長串複雜的參數(Constructor Pollution,例如 new User("John", 30, "Taiwan", null, true, ...))。

  • 步驟必須按照特定順序執行。

  • 問題: 如果將這些複雜的初始化邏輯全部寫在商業邏輯程式碼中,會導致程式碼極度臃腫且難以維護。

  • 解法: 像是 Builder(建造者模式) 或 Abstract Factory(抽象工廠) 就是專門用來把這些繁複的建造細節封裝起來,讓呼叫端只要簡單呼叫「請給我一個物件」即可。

3. 無法控制實例數量與資源開銷(Lifecycle & Resource Control)

直接用 new 的另一個問題是:呼叫端無法限制總共被建立了幾個物件。

  • 問題: 有些物件(如資料庫連線池、執行緒池、全域設定管理器)如果在系統中被 new 出好幾個實例,會導致記憶體暴增、資源衝突或資料不同步。

  • 解法: Singleton(單例模式) 就是為了防止外部隨意 new,強制控制整個生命週期中只能有一個實例。

4. 需要在執行時期(Runtime)才決定要建立哪種物件

有時候,要在寫程式(Compile time)的當下,根本不知道該建立哪一個類別的物件,必須根據使用者的輸入、檔案格式或環境變數來決定。

  • 問題: 如果用傳統的 new,會被迫寫出龐大且充滿擴充危機的 if-else 或 switch-case 判斷式。

  • 解法: Factory Method(工廠方法) 或 Prototype(原型模式) 允許系統在執行時期動態決定該實例化哪一個類別,甚至直接透過複製現有物件來衍生新物件。

💡 總結

直接用 new 就像是「自己動手做每一個零件」;而使用創建型模式,就像是「委託專門的工廠或師傅來幫你生產」。

  • 直接 new:適合簡單、小型、短期、不需要太高擴充性的腳本或小程式。

  • 創建型模式:適合需要易於維護、易於寫單元測試、架構需長期演進的中大型系統。

沒有留言:

張貼留言

有 Creational Patterns 的原因,是否是有些狀況不適合直接用 new 建造出一個物件來用?

  沒錯!您的直覺非常準確,這正是整個創建型模式(Creational Patterns)核心要解決的根本問題。 在軟體開發中,直接使用 new 關鍵字來建立物件(例如 MyClass obj = new MyClass(); )雖然直覺又方便,但在中大型系統或需要高度擴充性的...