You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

234 lines
6.2 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

"""
工厂方法模式 (Factory Method Pattern)
意图:定义一个用于创建对象的接口,让子类决定实例化哪个类。工厂方法使一个类的实例化延迟到其子类。
应用场景:
- 当一个类不知道它所必须创建的对象的类的时候
- 当一个类希望由它的子类来指定它所创建的对象的时候
- 当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候
结构:
- Product: 定义工厂方法所创建的对象的接口
- ConcreteProduct: 实现Product接口
- Creator: 声明工厂方法该方法返回一个Product类型的对象
- ConcreteCreator: 重写工厂方法以返回一个ConcreteProduct实例
"""
from abc import ABC, abstractmethod
class Product(ABC):
"""产品接口,定义所有具体产品共有的操作"""
@abstractmethod
def operation(self) -> str:
"""抽象操作方法"""
pass
class ConcreteProductA(Product):
"""具体产品A"""
def operation(self) -> str:
return "返回产品A的操作结果"
class ConcreteProductB(Product):
"""具体产品B"""
def operation(self) -> str:
return "返回产品B的操作结果"
class ConcreteProductC(Product):
"""具体产品C"""
def operation(self) -> str:
return "返回产品C的操作结果"
class Creator(ABC):
"""创建者抽象类,声明工厂方法"""
@abstractmethod
def factory_method(self) -> Product:
"""工厂方法,返回一个产品实例"""
pass
def some_operation(self) -> str:
"""业务逻辑依赖于factory_method创建的产品对象"""
# 调用工厂方法创建产品
product = self.factory_method()
# 使用产品执行操作
result = f"创建者:使用{product.__class__.__name__}执行操作\n{product.operation()}"
return result
class ConcreteCreatorA(Creator):
"""具体创建者A创建产品A"""
def factory_method(self) -> Product:
return ConcreteProductA()
class ConcreteCreatorB(Creator):
"""具体创建者B创建产品B"""
def factory_method(self) -> Product:
return ConcreteProductB()
class ConcreteCreatorC(Creator):
"""具体创建者C创建产品C"""
def factory_method(self) -> Product:
return ConcreteProductC()
# 扩展:参数化工厂方法
class ParameterizedCreator:
"""参数化的工厂类,根据参数创建不同的产品"""
@staticmethod
def create_product(product_type: str) -> Product:
"""根据参数创建产品
Args:
product_type: 产品类型标识
Returns:
Product: 创建的产品实例
Raises:
ValueError: 当产品类型无效时
"""
if product_type == "A":
return ConcreteProductA()
elif product_type == "B":
return ConcreteProductB()
elif product_type == "C":
return ConcreteProductC()
else:
raise ValueError(f"未知的产品类型: {product_type}")
# 实际应用示例:文档导出器
class DocumentExporter(ABC):
"""文档导出器接口"""
@abstractmethod
def export(self, content: str) -> str:
"""导出文档
Args:
content: 文档内容
Returns:
str: 导出结果
"""
pass
class PDFExporter(DocumentExporter):
"""PDF格式导出器"""
def export(self, content: str) -> str:
return f"PDF导出成功'{content}'转换为PDF格式"
class WordExporter(DocumentExporter):
"""Word格式导出器"""
def export(self, content: str) -> str:
return f"Word导出成功'{content}'转换为DOCX格式"
class HTMLExporter(DocumentExporter):
"""HTML格式导出器"""
def export(self, content: str) -> str:
return f"HTML导出成功'{content}'转换为HTML格式"
class DocumentExporterCreator(ABC):
"""文档导出器创建者抽象类"""
@abstractmethod
def create_exporter(self) -> DocumentExporter:
"""创建导出器的工厂方法"""
pass
def export_document(self, content: str) -> str:
"""导出文档的业务逻辑"""
exporter = self.create_exporter()
return exporter.export(content)
class PDFExporterCreator(DocumentExporterCreator):
"""PDF导出器创建者"""
def create_exporter(self) -> DocumentExporter:
return PDFExporter()
class WordExporterCreator(DocumentExporterCreator):
"""Word导出器创建者"""
def create_exporter(self) -> DocumentExporter:
return WordExporter()
class HTMLExporterCreator(DocumentExporterCreator):
"""HTML导出器创建者"""
def create_exporter(self) -> DocumentExporter:
return HTMLExporter()
def main():
"""演示工厂方法模式"""
print("=== 工厂方法模式演示 ===")
# 基本工厂方法模式演示
print("\n1. 基本工厂方法模式:")
creators = [
ConcreteCreatorA(),
ConcreteCreatorB(),
ConcreteCreatorC()
]
for creator in creators:
print(f"\n{creator.__class__.__name__}:")
print(creator.some_operation())
# 参数化工厂方法演示
print("\n2. 参数化工厂方法:")
try:
for product_type in ["A", "B", "C"]:
product = ParameterizedCreator.create_product(product_type)
print(f"\n创建产品类型 {product_type}:")
print(product.operation())
# 测试错误处理
ParameterizedCreator.create_product("D")
except ValueError as e:
print(f"\n异常处理测试: {e}")
# 实际应用示例:文档导出器
print("\n3. 实际应用示例 - 文档导出器:")
exporters = [
PDFExporterCreator(),
WordExporterCreator(),
HTMLExporterCreator()
]
document_content = "这是一篇测试文档内容"
for exporter in exporters:
print(f"\n{exporter.__class__.__name__}:")
print(exporter.export_document(document_content))
if __name__ == "__main__":
main()