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.

400 lines
9.5 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.

"""
抽象工厂模式 (Abstract Factory Pattern)
意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们的具体类。
应用场景:
- 系统要独立于它的产品的创建、组合和表示时
- 系统要由多个产品系列中的一个来配置时
- 当你要强调一系列相关的产品对象的设计以便进行联合使用时
- 当你提供一个产品类库,而只想暴露接口而不是实现时
结构:
- AbstractFactory: 声明创建抽象产品的接口
- ConcreteFactory: 实现创建具体产品的操作
- AbstractProduct: 声明一类产品的接口
- ConcreteProduct: 定义具体工厂创建的产品对象
- Client: 使用抽象工厂和抽象产品的接口
"""
from abc import ABC, abstractmethod
# 抽象产品族A
class AbstractProductA(ABC):
"""抽象产品A的接口"""
@abstractmethod
def useful_function_a(self) -> str:
"""产品A的有用功能"""
pass
# 具体产品A1
class ConcreteProductA1(AbstractProductA):
"""具体产品A1"""
def useful_function_a(self) -> str:
return "产品A1的有用功能"
# 具体产品A2
class ConcreteProductA2(AbstractProductA):
"""具体产品A2"""
def useful_function_a(self) -> str:
return "产品A2的有用功能"
# 抽象产品族B
class AbstractProductB(ABC):
"""抽象产品B的接口"""
@abstractmethod
def useful_function_b(self) -> str:
"""产品B的有用功能"""
pass
@abstractmethod
def another_useful_function_b(self, collaborator: AbstractProductA) -> str:
"""产品B与产品A协作的功能"""
pass
# 具体产品B1
class ConcreteProductB1(AbstractProductB):
"""具体产品B1"""
def useful_function_b(self) -> str:
return "产品B1的有用功能"
def another_useful_function_b(self, collaborator: AbstractProductA) -> str:
result = collaborator.useful_function_a()
return f"产品B1与{collaborator.__class__.__name__}协作: {result}"
# 具体产品B2
class ConcreteProductB2(AbstractProductB):
"""具体产品B2"""
def useful_function_b(self) -> str:
return "产品B2的有用功能"
def another_useful_function_b(self, collaborator: AbstractProductA) -> str:
result = collaborator.useful_function_a()
return f"产品B2与{collaborator.__class__.__name__}协作: {result}"
# 抽象工厂
class AbstractFactory(ABC):
"""抽象工厂接口,声明创建抽象产品的方法"""
@abstractmethod
def create_product_a(self) -> AbstractProductA:
"""创建产品A"""
pass
@abstractmethod
def create_product_b(self) -> AbstractProductB:
"""创建产品B"""
pass
# 具体工厂1
class ConcreteFactory1(AbstractFactory):
"""具体工厂1生产产品族1"""
def create_product_a(self) -> AbstractProductA:
return ConcreteProductA1()
def create_product_b(self) -> AbstractProductB:
return ConcreteProductB1()
# 具体工厂2
class ConcreteFactory2(AbstractFactory):
"""具体工厂2生产产品族2"""
def create_product_a(self) -> AbstractProductA:
return ConcreteProductA2()
def create_product_b(self) -> AbstractProductB:
return ConcreteProductB2()
# 客户端代码
class Client:
"""客户端类,使用抽象工厂和抽象产品"""
def __init__(self, factory: AbstractFactory):
"""初始化客户端
Args:
factory: 具体工厂实例
"""
self.factory = factory
def do_something(self) -> str:
"""使用工厂创建的产品执行操作"""
product_a = self.factory.create_product_a()
product_b = self.factory.create_product_b()
result = []
result.append(product_b.useful_function_b())
result.append(product_b.another_useful_function_b(product_a))
return "\n".join(result)
# 扩展:更复杂的抽象工厂示例 - UI组件工厂
class Button(ABC):
"""按钮抽象类"""
@abstractmethod
def render(self) -> str:
"""渲染按钮"""
pass
class Checkbox(ABC):
"""复选框抽象类"""
@abstractmethod
def render(self) -> str:
"""渲染复选框"""
pass
class TextField(ABC):
"""文本框抽象类"""
@abstractmethod
def render(self) -> str:
"""渲染文本框"""
pass
# Windows风格组件
class WindowsButton(Button):
"""Windows风格按钮"""
def render(self) -> str:
return "渲染Windows风格按钮"
class WindowsCheckbox(Checkbox):
"""Windows风格复选框"""
def render(self) -> str:
return "渲染Windows风格复选框"
class WindowsTextField(TextField):
"""Windows风格文本框"""
def render(self) -> str:
return "渲染Windows风格文本框"
# MacOS风格组件
class MacOSButton(Button):
"""MacOS风格按钮"""
def render(self) -> str:
return "渲染MacOS风格按钮"
class MacOSCheckbox(Checkbox):
"""MacOS风格复选框"""
def render(self) -> str:
return "渲染MacOS风格复选框"
class MacOSTextField(TextField):
"""MacOS风格文本框"""
def render(self) -> str:
return "渲染MacOS风格文本框"
# Linux风格组件
class LinuxButton(Button):
"""Linux风格按钮"""
def render(self) -> str:
return "渲染Linux风格按钮"
class LinuxCheckbox(Checkbox):
"""Linux风格复选框"""
def render(self) -> str:
return "渲染Linux风格复选框"
class LinuxTextField(TextField):
"""Linux风格文本框"""
def render(self) -> str:
return "渲染Linux风格文本框"
# UI组件工厂接口
class UIFactory(ABC):
"""UI组件工厂接口"""
@abstractmethod
def create_button(self) -> Button:
"""创建按钮"""
pass
@abstractmethod
def create_checkbox(self) -> Checkbox:
"""创建复选框"""
pass
@abstractmethod
def create_text_field(self) -> TextField:
"""创建文本框"""
pass
# Windows UI工厂
class WindowsUIFactory(UIFactory):
"""Windows UI组件工厂"""
def create_button(self) -> Button:
return WindowsButton()
def create_checkbox(self) -> Checkbox:
return WindowsCheckbox()
def create_text_field(self) -> TextField:
return WindowsTextField()
# MacOS UI工厂
class MacOSUIFactory(UIFactory):
"""MacOS UI组件工厂"""
def create_button(self) -> Button:
return MacOSButton()
def create_checkbox(self) -> Checkbox:
return MacOSCheckbox()
def create_text_field(self) -> TextField:
return MacOSTextField()
# Linux UI工厂
class LinuxUIFactory(UIFactory):
"""Linux UI组件工厂"""
def create_button(self) -> Button:
return LinuxButton()
def create_checkbox(self) -> Checkbox:
return LinuxCheckbox()
def create_text_field(self) -> TextField:
return LinuxTextField()
# 应用类
class Application:
"""应用类使用UI工厂创建界面"""
def __init__(self, factory: UIFactory):
"""初始化应用
Args:
factory: UI组件工厂
"""
self.factory = factory
self.button = None
self.checkbox = None
self.text_field = None
def create_ui(self):
"""创建用户界面"""
self.button = self.factory.create_button()
self.checkbox = self.factory.create_checkbox()
self.text_field = self.factory.create_text_field()
def render_ui(self) -> str:
"""渲染用户界面
Returns:
str: 渲染结果
"""
if not self.button:
self.create_ui()
result = []
result.append(self.button.render())
result.append(self.checkbox.render())
result.append(self.text_field.render())
return "\n".join(result)
def configure_application(os_type: str) -> Application:
"""根据操作系统类型配置应用
Args:
os_type: 操作系统类型
Returns:
Application: 配置好的应用实例
Raises:
ValueError: 当操作系统类型无效时
"""
factories = {
"windows": WindowsUIFactory(),
"macos": MacOSUIFactory(),
"linux": LinuxUIFactory()
}
if os_type.lower() not in factories:
raise ValueError(f"不支持的操作系统: {os_type}")
factory = factories[os_type.lower()]
return Application(factory)
def main():
"""演示抽象工厂模式"""
print("=== 抽象工厂模式演示 ===")
# 基本抽象工厂模式演示
print("\n1. 基本抽象工厂模式:")
factories = [
ConcreteFactory1(),
ConcreteFactory2()
]
for factory in factories:
print(f"\n使用{factory.__class__.__name__}:")
client = Client(factory)
print(client.do_something())
# UI组件工厂演示
print("\n2. UI组件工厂示例")
try:
for os_type in ["Windows", "MacOS", "Linux"]:
print(f"\n配置{os_type}风格界面:")
app = configure_application(os_type)
print(app.render_ui())
# 测试错误处理
configure_application("iOS")
except ValueError as e:
print(f"\n异常处理测试: {e}")
if __name__ == "__main__":
main()