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) }}
直播中

尚未有邦友留言

立即登入留言