使用工厂模式(Factory Pattern)的复杂示例,该示例具有实际业务意义,并包含不同的子类创建情况。
业务场景
假设我们有一个在线零售平台,该平台销售多种类型的商品(如电子产品、服装和书籍)。每种商品都有其特定的属性和行为。例如,电子产品可能有保修期,服装可能有尺码和颜色,而书籍可能有ISBN号和作者。
为了管理这些不同类型的商品,我们可以使用工厂模式来根据商品类型创建相应的商品对象。
代码实现
from abc import ABC, abstractmethod
from typing import Dict, Union
# 商品基类(抽象类)
class Product(ABC):
@abstractmethod
def display_info(self) -> None:
pass
# 电子产品类
class ElectronicProduct(Product):
def __init__(self, name: str, warranty_period: int):
self.name = name
self.warranty_period = warranty_period # 保修期(月)
def display_info(self) -> None:
print(f"Product: {self.name}, Warranty Period: {self.warranty_period} months")
# 服装类
class ClothingProduct(Product):
def __init__(self, name: str, size: str, color: str):
self.name = name
self.size = size # 尺码
self.color = color # 颜色
def display_info(self) -> None:
print(f"Product: {self.name}, Size: {self.size}, Color: {self.color}")
# 书籍类
class BookProduct(Product):
def __init__(self, name: str, isbn: str, author: str):
self.name = name
self.isbn = isbn # ISBN号
self.author = author # 作者
def display_info(self) -> None:
print(f"Product: {self.name}, ISBN: {self.isbn}, Author: {self.author}")
# 商品工厂类
class ProductFactory:
@staticmethod
def create_product(product_type: str, **kwargs: Dict[str, Union[str, int]]) -> Product:
if product_type == "electronic":
return ElectronicProduct(kwargs["name"], kwargs["warranty_period"])
elif product_type == "clothing":
return ClothingProduct(kwargs["name"], kwargs["size"], kwargs["color"])
elif product_type == "book":
return BookProduct(kwargs["name"], kwargs["isbn"], kwargs["author"])
else:
raise ValueError(f"Unknown product type: {product_type}")
# 使用示例
product_cases = [
{"type": "electronic", "name": "Laptop", "warranty_period": 24},
{"type": "clothing", "name": "T-Shirt", "size": "M", "color": "Blue"},
{"type": "book", "name": "Python Programming", "isbn": "1234567890", "author": "John Doe"}
]
for case in product_cases:
product = ProductFactory.create_product(**case)
product.display_info()
解释
-
抽象产品类:
Product
是一个抽象基类,定义了所有产品共有的接口display_info
。 -
具体产品类:
ElectronicProduct
、ClothingProduct
和BookProduct
是Product
的子类,分别实现了电子产品、服装和书籍的具体属性和行为。 -
工厂类:
ProductFactory
是一个静态方法工厂类,它根据传入的product_type
和其他关键字参数来创建并返回相应的产品对象。 -
使用示例:
product_cases
列表包含了多个商品创建案例,每个案例都是一个字典,包含了产品类型和必要的属性。通过遍历这个列表,并使用ProductFactory.create_product
方法,我们可以动态地创建并显示不同类型的商品对象。
优点
- 代码解耦:工厂模式将对象的创建逻辑与客户端代码分离,使得客户端代码更加简洁和易于维护。
- 扩展性:如果需要添加新的产品类型,只需添加一个新的产品类和相应的工厂逻辑,而不需要修改现有的客户端代码。
- 灵活性:工厂模式允许根据运行时条件动态地创建对象,提高了代码的灵活性和可配置性。
变体
使用这种方式:
@classmethod
def create()
基类与工厂方法合并:Product
类现在不仅是一个抽象基类,还包含了一个类方法 create
,该方法根据传入的 product_type
和其他参数来创建并返回适当的子类实例。
from abc import ABC, abstractmethod
from typing import Dict, Union
# 商品基类(抽象类),同时包含工厂方法
class Product(ABC):
@abstractmethod
def display_info(self) -> None:
pass
@classmethod
def create(cls, product_type: str, **kwargs: Dict[str, Union[str, int]]) -> 'Product':
if cls is Product: # 确保不会在子类中意外调用基类的create方法
if product_type == "electronic":
return ElectronicProduct(kwargs["name"], kwargs["warranty_period"])
elif product_type == "clothing":
return ClothingProduct(kwargs["name"], kwargs["size"], kwargs["color"])
elif product_type == "book":
return BookProduct(kwargs["name"], kwargs["isbn"], kwargs["author"])
else:
raise ValueError(f"Unknown product type: {product_type}")
else:
# 如果在子类中调用,则应该抛出异常或进行其他处理
raise NotImplementedError("Subclasses should not call the create method directly.")
# 电子产品类
class ElectronicProduct(Product):
def __init__(self, name: str, warranty_period: int):
self.name = name
self.warranty_period = warranty_period # 保修期(月)
def display_info(self) -> None:
print(f"Product: {self.name}, Warranty Period: {self.warranty_period} months")
# 服装类
class ClothingProduct(Product):
def __init__(self, name: str, size: str, color: str):
self.name = name
self.size = size # 尺码
self.color = color # 颜色
def display_info(self) -> None:
print(f"Product: {self.name}, Size: {self.size}, Color: {self.color}")
# 书籍类
class BookProduct(Product):
def __init__(self, name: str, isbn: str, author: str):
self.name = name
self.isbn = isbn # ISBN号
self.author = author # 作者
def display_info(self) -> None:
print(f"Product: {self.name}, ISBN: {self.isbn}, Author: {self.author}")
# 使用示例
product_cases = [
{"type": "electronic", "name": "Laptop", "warranty_period": 24},
{"type": "clothing", "name": "T-Shirt", "size": "M", "color": "Blue"},
{"type": "book", "name": "Python Programming", "isbn": "1234567890", "author": "John Doe"}
]
for case in product_cases:
product = Product.create(**case) # 直接通过基类调用工厂方法
product.display_info()
这种设计模式的优点是它提供了一个集中的创建点,使得添加新产品类型变得更加容易,因为只需要在 Product
类的 create
方法中添加新的条件分支即可。然而,随着产品类型的增加,create
方法可能会变得庞大且难以维护。在实际应用中,可能会考虑使用更复杂的工厂模式变体(如工厂方法模式或抽象工厂模式)来进一步解耦和简化代码。