iT邦幫忙

2023 iThome 鐵人賽

DAY 7
0
Software Development

深入淺出設計模式 - 使用 C++系列 第 7 篇

[Day 07] 經典比較 — Simple Factory / Factory / Abstract Factory

  • 分享至 

  • xImage
  •  

列表比較

Simple Factory Factory Abstract Factory
定義 單一個 Method 來決定要 Return 哪一種 Product 的實例 定義了一個創建對象的 Interface,但由子類別決定實例化哪一個類。Factory Method 讓類的實例化推遲到子類 提供一個Interface,讓該Interface的子類別決定實例化哪一系列的產品家族
使用時機 要創建的對象相對較少 (簡單) 當系統需要多個產品家族中的一員時,且系統只知道需要某個具體類(Concrete Class) 的時候 當系統中涉及到多個產品系列,但系統只消費其中一個系列的產品時
抽象性 低 中 高
擴展性 差(需修改工廠方法) 較好(增加新的具體工廠) 較好(增加新的具體工廠及產品家族)
差異 Simple Factory 是最簡單的工廠模式,它只包含一個工廠類,負責所有產品的創建。當新的產品被加入時,需要修改工廠方法 Factory Method 使用多個工廠類,每個工廠類對應一種產品。當需要擴展產品時,只需要增加相對應的工廠類 Abstract Factory 使用多個產品家族,每個產品家族由多個產品組成。當需要擴展產品家族或產品時,可以增加相對應的工廠類和產品類

優缺點分析 (僅供參考)

Simple Factory

  • Pros:
    1. Client 端僅需知道具體的工廠名稱,便可得到所需的產品對象,無需知道產品的具體創建過程
    2. 可以減少 Client 端的職責和過度的依賴,使 Client 端無需擔心在新增產品時需要新增和修改大量的代碼 (與 If(Type I) / Else if(Type II)...的寫法相比較)
  • Cons:
    1. 工廠類的職責過重,違反了高內聚,單一責任的設計原則 (SRP)
    2. 較難擴展,一旦需要增加新的產品就必須修改工廠方法的邏輯,違反開放封閉原則 (OCP)

Factory Method

  • Pros:
    1. 用戶只需要知道具體工廠的角色,而不需要知道具體產品的創建過程
    2. 符合開放/封閉原則,當需要新增產品時只需擴展一個相對應的工廠類即可
    3. 有助於降低系統的耦合,工廠方法模式可以避免直接創建對象的實例,而是讓子類別完成這個工作
  • Cons:
    1. 每增加一個產品,都需要增加一個相對應的工廠,這會增加系統的類數,導致更多的程式碼要維護
    2. 所有的具體工廠類都需要有外部輸入,如果 Client 端使用不正確,可能會導致系統在運行時的錯誤 (存取錯 Reference、Pointer...等,通常會搭配其他 Pattern 一起使用 (Builder / Singleton...)

Abstract Factory

  • Pros:
    1. 可以確保同時使用的產品都來自於同一產品家族,這有助於保持系統的一致性
    2. 符合開放/封閉原則,當需要新增一個產品家族或產品時,只需要擴展相對應的工廠和產品類即可
    3. 系統的靈活性和擴展性都非常高
  • Cons:
    1. 增加了系統的抽象性和理解難度
    2. 當需要擴展新的產品家族時,需要修改多個類,增加了系統的維護難度 (更多更多的程式碼要維護)
    3. 可能會導致過多的 Class 和 Interface,增加系統的複雜性

Reference

[1]. https://www.baeldung.com/cs/factory-method-vs-factory-vs-abstract-factory
[2]. https://refactoring.guru/design-patterns/factory-method
[3]. https://refactoring.guru/design-patterns/abstract-factory


上一篇
[Day 06] 讓工廠再解藕 - 抽象工廠模式 (Abstract Factory Pattern)
下一篇
[Day 08] 獨一無二的物件 - 單例模式 (Singleton Pattern)
系列文
深入淺出設計模式 - 使用 C++ 共 37 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言