工廠模式的核心思想:封裝對象創建過程、解耦對象使用與創建 。
示例代碼:
from enum import Enum# 基類:人類
class Person:species = 'Homo sapiens'def __init__(self, name):self.name = namedef __str__(self):return f"{self.__class__.__name__}: {self.name}"# 子類:成年人
class Adult(Person):def can_vote(self):return True # 成年人有投票權# 子類:未成年人
class Minor(Person):def can_vote(self):return False # 未成年人無投票權# 子類:匿名人士
class AnonymousPerson(Person):def __init__(self):super().__init__('Anonymous') # 固定名稱為Anonymous# 枚舉:定義支持的人物類型
class PersonType(Enum):ADULT = 1MINOR = 2ANONYMOUS = 3# 工廠類:負責創建不同類型的Person對象
class PersonFactory:@staticmethoddef create_person(person_type, name=None):"""根據類型創建不同的Person對象:param person_type: PersonType枚舉值,指定要創建的對象類型:param name: 名稱(匿名類型不需要此參數):return: 對應的Person子類實例"""if person_type == PersonType.ADULT:if not name:raise ValueError("創建成年人需要提供姓名")return Adult(name)elif person_type == PersonType.MINOR:if not name:raise ValueError("創建未成年人需要提供姓名")return Minor(name)elif person_type == PersonType.ANONYMOUS:return AnonymousPerson() # 匿名類型無需姓名else:raise ValueError(f"不支持的人物類型: {person_type}")# 使用示例
if __name__ == "__main__":# 通過工廠創建不同類型的對象adult = PersonFactory.create_person(PersonType.ADULT, "Alice")minor = PersonFactory.create_person(PersonType.MINOR, "Bob")anonymous = PersonFactory.create_person(PersonType.ANONYMOUS)print(adult) # 輸出:Adult: Aliceprint(minor) # 輸出:Minor: Bobprint(anonymous) # 輸出:AnonymousPerson: Anonymousprint(adult.can_vote()) # 輸出:Trueprint(minor.can_vote()) # 輸出:False
以上代碼通過創建獨立的工廠類,并通過工廠類來管理不同類型對象的創建。
這個實現的特點(符合標準工廠模式):
分離的工廠類
創建了獨立的PersonFactory
類,專門負責對象的創建邏輯,而Person
及其子類只關注自身的業務邏輯(如can_vote
方法)。這種分離符合 "單一職責原則"。通過類型控制創建
使用PersonType
枚舉明確支持的對象類型,調用者只需指定類型和必要參數(如姓名),無需直接實例化具體子類(如Adult()
、Minor()
)。封裝創建細節
工廠類內部處理了不同類型對象的創建條件(如匿名對象不需要姓名),調用者無需關心這些細節,只需通過統一的create_person
方法獲取對象。易于擴展
如果需要新增Person
類型(如Senior
老年人),只需:- 創建
Senior
子類繼承Person
- 在
PersonType
枚舉中添加SENIOR
- 在工廠類的
create_person
方法中增加對應分支
無需修改現有業務邏輯,符合 "開閉原則"。
- 創建
統一的接口
所有通過工廠創建的對象都遵循Person
基類的接口規范(如都有name
屬性和__str__
方法),調用者可以統一處理這些對象,無需區分具體類型。
這種實現比之前的類方法方式更接近標準工廠模式,尤其在需要管理多種對象類型、創建邏輯復雜的場景下,優勢會更加明顯。