一、什么是工廠函數?
工廠函數(Factory Function)是一種設計模式,其核心是通過一個函數來 創建并返回對象,而不是直接使用 new
或構造函數實例化對象。它封裝了對象的創建過程,使代碼更靈活、可維護。
二、工廠函數的目的與作用
目的 | 作用 |
---|---|
解耦對象創建邏輯 | 將對象的創建與使用分離,調用者無需關心對象的具體實現細節。 |
延遲實例化 | 僅在需要時創建對象,避免資源浪費(如內存、CPU)。 |
支持動態參數 | 根據輸入參數返回不同類型的對象(多態性)。 |
統一接口 | 提供標準化的對象創建方式,便于擴展和維護。 |
三、工廠函數示例
1. 簡單工廠:形狀創建
假設需要根據用戶輸入創建不同形狀(圓形、矩形),直接實例化會導致代碼冗余和耦合:
# 無工廠函數的問題
if shape_type == 'circle':obj = Circle(radius=5)
elif shape_type == 'rectangle':obj = Rectangle(width=3, height=4)
使用工廠函數優化后:
# 定義形狀類
class Circle:def __init__(self, radius):self.radius = radiusclass Rectangle:def __init__(self, width, height):self.width = widthself.height = height# 工廠函數
def shape_factory(shape_type, **kwargs):if shape_type == 'circle':return Circle(**kwargs)elif shape_type == 'rectangle':return Rectangle(**kwargs)else:raise ValueError("Unknown shape type")# 調用
circle = shape_factory('circle', radius=5)
rectangle = shape_factory('rectangle', width=3, height=4)
2. Mininet 中的工廠函數
在 Mininet 自定義拓撲中,lambda: MyTopo()
是一個工廠函數:
# 工廠函數:延遲創建 MyTopo 實例
topos = {'mytopo': (lambda: MyTopo())}
當 Mininet 需要構建拓撲時,會調用 topos['mytopo']()
執行 Lambda 函數,動態生成 MyTopo
實例。
四、工廠函數的優勢
1. 避免緊耦合
- 直接實例化:調用方需知道具體類的構造函數。
- 工廠函數:調用方只需傳遞參數,無需了解類細節。
2. 靈活擴展
新增對象類型時,只需修改工廠函數,無需修改調用代碼。
# 擴展支持三角形
class Triangle:def __init__(self, base, height):self.base = baseself.height = heightdef shape_factory(shape_type, **kwargs):# 原有邏輯...elif shape_type == 'triangle':return Triangle(**kwargs)
3. 資源管理
延遲實例化可節省內存和計算資源,尤其是在對象創建成本高時(如數據庫連接)。
五、工廠函數 vs 直接實例化
場景 | 直接實例化 | 工廠函數 |
---|---|---|
簡單對象創建 | 適合(如 obj = MyClass() ) | 過渡設計 |
復雜/條件化創建 | 代碼冗余,難以維護 | 統一管理,邏輯清晰 |
需要延遲加載 | 無法實現 | 天然支持 |
多態性需求 | 需手動判斷類型 | 封裝在工廠中,對調用方透明 |
六、工廠模式的其他形式
-
工廠方法模式
每個子類實現自己的工廠方法(面向對象設計中的經典模式)。 -
抽象工廠模式
創建一組相關或依賴對象的接口(如 GUI 庫中的跨平臺組件)。
七、總結
- 核心思想:工廠函數通過封裝對象創建邏輯,提升代碼的靈活性和可維護性。
- 在 Mininet 中的應用:
lambda: MyTopo()
作為工廠函數,確保 Mininet 在運行時動態創建拓撲實例。 - 適用場景:對象創建邏輯復雜、需要延遲加載或支持多態性時優先使用。
通過合理使用工廠函數,可以顯著提高代碼的模塊化程度,降低系統各部分之間的依賴。