iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 3
0

什麼是Factory Method?

Factory Method 工廠方法是一種創建型設計模式:Superclass 先粗略定義 Object 的創建方法,但允許 Subclass 詳細定義 Object 的創建方法。

舉例來說,運輸總公司(Superclass)持有一張廣義運輸工具的設計圖(Interface),總公司只宣告要生產廣義的運輸工具(Product),這些運輸工具會在南北之間來回送貨(運作邏輯),但沒寫要生產貨車還是船,然後根據設計圖,陸路運輸公司(Subclass)製造貨車(Product),海路運輸公司(Subclass)製造船(Product)。同時陸路運輸公司、海路運輸公司都直接利用設計圖裡面寫好的送貨方法。

比較正式地說,Superclass 透過 Interface 定義某類 Object 粗略的創建方法,並且定義這類 Object 共同的運作邏輯,然後再讓 Subclass 詳細重寫該類 Object 的創建方法。而這些透過 Factory Method 產生的 Object 稱為 Product。

不用吧,明明就有兩個比較簡單的設計方法呀

  1. 讓陸路運輸公司獨立生產貨車,設計貨車的送貨方法;而海路運輸公司獨立生產船,設計船的送貨方法呢?
    陸路運輸公司、海路運輸公司都自己寫了一份送貨方法,不只多餘,每次要改什麼還要改兩次。如果之後要加入飛機空運,送貨方法再寫一次,崩潰。

  2. 運輸總公司一起生產貨車、船,設計一套送貨邏輯給船跟貨車一起用呢?
    送貨邏輯裡面就會夾雜很多 if/else:看到貨車就跑陸路,看到船就走海路。之後又要加入飛機空運,再度崩潰。

除了以上好處,Factory Method 同時也符合計算機科學中的兩個設計原則,首先是單一功能原則:創建 product 的程式碼都在同一個地方 (factory_method),而使其更容易維護;第二則是開閉原則:因為送貨方法和 product 類型無關,所以就算加入新的 product 類型也無需更改送貨方法。

而壞處呢,一大堆 subclasses 會讓程式碼變的更複雜,但無論使用 Factory Method 與否,一大堆subclasses/classes 在這種情境中難以避免的。

來張圖吧

02_factory

把例子寫成python吧

from abc import ABC

class Logistics(ABC):
	
    # 初始化透過factory method創建product
    def __init__(self):
        self.product = self.factory_method()
       
	# 抽象的product創建方法
    def factory_method(self):
        pass
	
    # 卡車和船共通的送貨邏輯
    def run_delivery(self):
        print("Running some complex operations")        
        self.product.deliver()

# 陸路運輸公司
class RoadLogistics(Logistics):
	
    # 重寫工廠方法
    def factory_method(self):
        return Truck()

# 海路運輸公司
class SeaLogistics(Logistics):
	
    # 重寫工廠方法
    def factory_method(self):
        return Ship()

# 廣義的運輸工具
class Transport(ABC):

	# 會運輸
	def deliver(self):
    	pass

# 貨車
class Truck(Transport):

    # 會走陸路運輸
    def deliver(self):
    	print("truck delivering stuff")

# 船
class Ship(Transport):

    # 會走海路運輸
    def deliver(self):
        print("ship delivering stuff")


if __name__ == "__main__":
	# 假設陸路運輸公司那邊要製造貨車來送貨
    logistics = RoadLogistics()
    logistics.run_delivery()

最後呢

在一般專案初期,我們可以先使用較簡單的 Factory Method 來創建 Object,之後如果想要更靈活地創建 Object,我們也可以改用較複雜的 Abstract Factory,Prototype,或是 Builder 等創建型設計模式。

等一下,Abstract Factory、Prototype、Builder又是什麼東西?

想了解更多,就請持續關注我們接下來的文章吧!

Reference

  1. Dive Into Design Patterns by Alexander Shvets
  2. https://refactoring.guru
  3. https://sourcemaking.com

作者:Allen


上一篇
別急!進入 Design Patterns 的行前說明
下一篇
[Design Pattern] Builder 建造者模式
系列文
什麼?又是/不只是 Design Patterns!?32

1 則留言

0
ytyubox
iT邦新手 5 級 ‧ 2019-09-20 00:37:18

自學 Design pattern 以來一值不懂創建的箭頭是哪一個?

我要留言

立即登入留言