工厂模式的核心思想:封装对象创建过程、解耦对象使用与创建 。
示例代码:
python
from enum import Enum
# 基类:人类
class Person:
species = 'Homo sapiens'
def __init__(self, name):
self.name = name
def __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 = 1
MINOR = 2
ANONYMOUS = 3
# 工厂类:负责创建不同类型的Person对象
class PersonFactory:
@staticmethod
def 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: Alice
print(minor) # 输出:Minor: Bob
print(anonymous) # 输出:AnonymousPerson: Anonymous
print(adult.can_vote()) # 输出:True
print(minor.can_vote()) # 输出:False
以上代码通过创建独立的工厂类,并通过工厂类来管理不同类型对象的创建。
这个实现的特点(符合标准工厂模式):
-
分离的工厂类
创建了独立的
PersonFactory
类,专门负责对象的创建逻辑,而Person
及其子类只关注自身的业务逻辑(如can_vote
方法)。这种分离符合 "单一职责原则"。 -
通过类型控制创建
使用
PersonType
枚举明确支持的对象类型,调用者只需指定类型和必要参数(如姓名),无需直接实例化具体子类(如Adult()
、Minor()
)。 -
封装创建细节
工厂类内部处理了不同类型对象的创建条件(如匿名对象不需要姓名),调用者无需关心这些细节,只需通过统一的
create_person
方法获取对象。 -
易于扩展
如果需要新增
Person
类型(如Senior
老年人),只需:- 创建
Senior
子类继承Person
- 在
PersonType
枚举中添加SENIOR
- 在工厂类的
create_person
方法中增加对应分支
无需修改现有业务逻辑,符合 "开闭原则"。
- 创建
-
统一的接口
所有通过工厂创建的对象都遵循
Person
基类的接口规范(如都有name
属性和__str__
方法),调用者可以统一处理这些对象,无需区分具体类型。
这种实现比之前的类方法方式更接近标准工厂模式,尤其在需要管理多种对象类型、创建逻辑复杂的场景下,优势会更加明显。