前言
接著上一篇的故事工廠模式繼續,手機要出廠,顯然光一個手機肯定是不行的,還需要包裝盒、充電器等等東西。我們按照上一篇提到的工廠模式,去建立新的工廠是一點都沒有問題的。但是思考一下這樣子做會帶來的問題,顯然工廠太多了,將包裝盒、充電器全部分散到各個工廠,組裝什麼的也是一個大問題,那麼有沒有更好的辦法呢?答案是肯定的,抽象工廠模式。
抽象工廠意圖
提供一個建立一系列相關或相互依賴物件的介面,而無需制定它們具體的累。
別名
案例
第三階段
光生產手機遠遠不夠,還需要生產其他配件,分散到新的工廠成本太高,也不利於維護,那就把一個型別的手機所需要的所有東西,都放到一個工廠完成,小米工廠生產小米手機以及小米手機配套的東西,蘋果手機生產蘋果手機以及蘋果手機配套的東西,客戶只需要關心要什麼手機就行了。
第三階段 UML 圖
讓我們藉助 UML 圖直觀瞭解一下這個時候工廠的樣子
第三階段程式碼
通過程式碼去實現這個邏輯
from abc import ABC, abstractmethod
# 抽象手機
class AbstractMobile(ABC):
@abstractmethod
def make(self):
pass
class XiaoMiMobile(AbstractMobile):
def make(self):
print("make xiaomi mobile")
class AppleMobile(AbstractMobile):
def make(self):
print("make apple mobile")
# 抽象手機配件
class AbstractOthers(ABC):
@abstractmethod
def make(self):
pass
class XiaoMiOthers(AbstractMobile):
def make(self):
print("make xiaomi others")
class AppleOthers(AbstractMobile):
def make(self):
print("make apple others")
# 抽象工廠
class AbstractFactory(ABC):
@abstractmethod
def create_mobile(self) -> AbstractMobile:
pass
@abstractmethod
def create_others(self) -> AbstractOthers:
pass
class XiaoMiFactory(AbstractFactory):
def create_mobile(self) -> XiaoMiMobile:
return XiaoMiMobile().make()
def create_others(self) -> XiaoMiOthers:
return XiaoMiOthers().make()
class AppleFactory(AbstractFactory):
def create_mobile(self) -> AppleMobile:
return AppleMobile().make()
def create_others(self) -> AppleOthers:
return AppleOthers().make()
def client(factory: AbstractFactory) -> None:
product_mobile = factory.create_mobile()
product_others = factory.create_others()
if __name__ == "__main__":
client(XiaoMiFactory())
client(AppleFactory())
看一下執行結果:
make xiaomi mobile
make xiaomi others
make apple mobile
make apple others
總結
如果程式碼需要與多個不同系列的相關產品互動, 但是由於無法提前獲取相關資訊, 或者出於對未來擴充套件性的考慮, 你不希望程式碼基於產品的具體類進行構建, 在這種情況下, 你可以使用抽象工廠。
在設計良好的程式中, 每個類僅負責一件事。 如果一個類與多種型別產品互動, 就可以考慮將工廠方法抽取到獨立的工廠類或具備完整功能的抽象工廠類中。
抽象工廠的優缺點
優點
- 你可以確保同一工廠生成的產品相互匹配。
- 你可以避免客戶端和具體產品程式碼的耦合。
- 單一職責原則。 你可以將產品生成程式碼抽取到同一位置, 使得程式碼易於維護。
- 開閉原則。 嚮應用程式中引入新產品變體時, 你無需修改客戶端程式碼
缺點
- 由於採用該模式需要嚮應用中引入眾多介面和類, 程式碼可能會比之前更加複雜,即產品族擴充套件非常困難