创建型模式
创建型模式
创建型模式专注于对象的创建机制,将对象的创建与使用分离。本文将介绍三种高级创建型模式:建造者模式、原型模式和抽象工厂模式。
建造者模式
建造者模式将复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。适用于创建过程复杂、步骤多的对象。
建造者实现
from typing import Optional, List
class HTTPRequest:
"""HTTP请求对象"""
def __init__(self):
self.method = "GET"
self.url = ""
self.headers: dict = {}
self.body: Optional[str] = None
self.timeout: int = 30
self.retries: int = 0
def __str__(self):
return (f"HTTPRequest(method={self.method}, url={self.url}, "
f"headers={self.headers}, timeout={self.timeout})")
class RequestBuilder:
"""HTTP请求建造者"""
def __init__(self):
self._request = HTTPRequest()
def set_method(self, method: str) -> 'RequestBuilder':
self._request.method = method.upper()
return self
def set_url(self, url: str) -> 'RequestBuilder':
self._request.url = url
return self
def add_header(self, key: str, value: str) -> 'RequestBuilder':
self._request.headers[key] = value
return self
def set_body(self, body: str) -> 'RequestBuilder':
self._request.body = body
return self
def set_timeout(self, timeout: int) -> 'RequestBuilder':
self._request.timeout = timeout
return self
def set_retries(self, retries: int) -> 'RequestBuilder':
self._request.retries = retries
return self
def build(self) -> HTTPRequest:
"""构建最终的请求对象"""
if not self._request.url:
raise ValueError("URL不能为空")
request = self._request
self._request = HTTPRequest() # 重置,支持重复使用
return request
class RequestDirector:
"""请求Director,封装常见的请求构建过程"""
@staticmethod
def create_json_request(url: str, data: str) -> HTTPRequest:
builder = RequestBuilder()
return (builder
.set_method("POST")
.set_url(url)
.add_header("Content-Type", "application/json")
.set_body(data)
.set_timeout(60)
.build())
@staticmethod
def create_api_request(url: str, auth_token: str) -> HTTPRequest:
builder = RequestBuilder()
return (builder
.set_method("GET")
.set_url(url)
.add_header("Authorization", f"Bearer {auth_token}")
.add_header("Accept", "application/json")
.set_retries(3)
.build())
# 使用示例
request = (RequestBuilder()
.set_method("PUT")
.set_url("https://api.example.com/users/123")
.add_header("Content-Type", "application/json")
.add_header("Authorization", "Bearer token123")
.set_body('{"name": "张三"}')
.set_timeout(30)
.build())
print(request)
# 使用Director创建标准请求
json_request = RequestDirector.create_json_request(
"https://api.example.com/data",
'{"key": "value"}'
)
原型模式
原型模式通过复制现有的对象来创建新对象,避免了重新初始化对象的开销。特别适合创建成本高的对象。
使用copy模块
import copy
from typing import Dict, List, Any
class Car:
"""汽车原型"""
def __init__(self, model: str, color: str, features: List[str]):
self.model = model
self.color = color
self.features = features.copy()
self.engine = None
self.transmission = None
def clone(self, deep: bool = True) -> 'Car':
"""克隆汽车对象"""
if deep:
return copy.deepcopy(self)
else:
return copy.copy(self)
def __str__(self):
return (f"Car(model={self.model}, color={self.color}, "
f"features={self.features})")
class CarPrototypeRegistry:
"""汽车原型注册表"""
def __init__(self):
self._prototypes: Dict[str, Car] = {}
def register(self, name: str, car: Car):
"""注册原型"""
self._prototypes[name] = car
def clone(self, name: str, **kwargs) -> Car:
"""克隆原型并可选择性修改属性"""
if name not in self._prototypes:
raise ValueError(f"未找到原型: {name}")
car = self._prototypes[name].clone()
# 应用自定义属性
for key, value in kwargs.items():
setattr(car, key, value)
return car
# 创建原型
base_sedan = Car("基础轿车", "白色", ["空调", "电动车窗"])
base_suv = Car("基础SUV", "黑色", ["空调", "电动车窗", "天窗", "导航"])
# 注册原型
registry = CarPrototypeRegistry()
registry.register("sedan", base_sedan)
registry.register("suv", base_suv)
# 从原型创建变体
custom_sedan = registry.clone("sedan", color="红色", features=["空调", "电动车窗", "真皮座椅"])
print(custom_sedan) # Car(model=基础轿车, color=红色, features=['空调', '电动车窗', '真皮座椅'])
# 原型未被修改
print(base_sedan) # Car(model=基础轿车, color=白色, features=['空调', '电动车窗'])
深拷贝与浅拷贝
import copy
class ComplexObject:
"""包含嵌套对象的复杂对象"""
def __init__(self):
self.simple_list = [1, 2, 3]
self.nested_dict = {"key": [4, 5, 6]}
def __str__(self):
return f"list={self.simple_list}, dict={self.nested_dict}"
# 原始对象
original = ComplexObject()
# 浅拷贝 - 嵌套对象共享引用
shallow = copy.copy(original)
shallow.simple_list.append(4)
shallow.nested_dict["key"].append(7)
print(f"Original: {original}") # list=[1, 2, 3], dict={'key': [4, 5, 6, 7]}
print(f"Shallow: {shallow}") # list=[1, 2, 3, 4], dict={'key': [4, 5, 6, 7]}
# 深拷贝 - 完全独立的副本
original2 = ComplexObject()
deep = copy.deepcopy(original2)
deep.simple_list.append(4)
deep.nested_dict["key"].append(7)
print(f"Original2: {original2}") # list=[1, 2, 3], dict={'key': [4, 5, 6]}
print(f"Deep: {deep}") # list=[1, 2, 3, 4], dict={'key': [4, 5, 6, 7]}
抽象工厂模式
抽象工厂模式提供一个创建一系列相关对象的接口,而无需指定它们的具体类。
from abc import ABC, abstractmethod
from typing import Tuple
class Button(ABC):
"""按钮抽象类"""
@abstractmethod
def render(self) -> str:
pass
class TextField(ABC):
"""文本框抽象类"""
@abstractmethod
def render(self) -> str:
pass
class Checkbox(ABC):
"""复选框抽象类"""
@abstractmethod
def render(self) -> str:
pass
class WindowsButton(Button):
def render(self) -> str:
return "[Windows按钮]"
class WindowsTextField(TextField):
def render(self) -> str:
return "(Windows文本框)"
class WindowsCheckbox(Checkbox):
def render(self) -> str:
return "☐ Windows复选框"
class MacButton(Button):
def render(self) -> str:
return "[Mac按钮]"
class MacTextField(TextField):
def render(self) -> str:
return "(Mac文本框)"
class MacCheckbox(Checkbox):
def render(self) -> str:
return "☑ Mac复选框"
class UIFactory(ABC):
"""UI工厂抽象类"""
@abstractmethod
def create_button(self) -> Button:
pass
@abstractmethod
def create_text_field(self) -> TextField:
pass
@abstractmethod
def create_checkbox(self) -> Checkbox:
pass
class WindowsUIFactory(UIFactory):
"""Windows UI工厂"""
def create_button(self) -> Button:
return WindowsButton()
def create_text_field(self) -> TextField:
return WindowsTextField()
def create_checkbox(self) -> Checkbox:
return WindowsCheckbox()
class MacUIFactory(UIFactory):
"""Mac UI工厂"""
def create_button(self) -> Button:
return MacButton()
def create_text_field(self) -> TextField:
return MacTextField()
def create_checkbox(self) -> Checkbox:
return MacCheckbox()
class Dialog:
"""对话框,使用抽象工厂创建UI组件"""
def __init__(self, factory: UIFactory):
self.factory = factory
self.button = factory.create_button()
self.text_field = factory.create_text_field()
self.checkbox = factory.create_checkbox()
def render(self) -> str:
return f"{self.button.render()} {self.text_field.render()} {self.checkbox.render()}"
# 根据平台选择工厂
import platform
factory = MacUIFactory() if platform.system() == "Darwin" else WindowsUIFactory()
dialog = Dialog(factory)
print(dialog.render())
模式对比
| 模式 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 建造者模式 | 创建过程复杂,需要多个步骤 | 灵活,可创建不同表示 | 增加复杂度 |
| 原型模式 | 对象创建成本高 | 性能好,避免重复初始化 | 深拷贝可能有问题 |
| 抽象工厂 | 需要创建一系列相关对象 | 一致性,易于扩展 | 添加新类型困难 |
创建型模式的选择取决于具体需求:简单对象用工厂方法,复杂对象用建造者,需要复用现有对象用原型,需要创建产品族用抽象工厂。