Python 设计模式详解 —— 掌握软件设计的通用解决方案
一、引言:什么是设计模式?
设计模式(Design Patterns) 是软件开发中常见问题的可重用解决方案。它们不是具体的代码,而是一种设计思想或模板,帮助开发者构建灵活、可维护、可扩展的系统。
📌 设计模式 ≠ 代码模板,而是解决特定设计问题的最佳实践。
为什么学习设计模式?
- 提高代码的可维护性和可扩展性
- 促进团队间的沟通效率(使用通用术语)
- 避免重复造轮子
- 写出更Pythonic的高质量代码
二、设计模式的三大分类
根据目的,设计模式分为三类:
类别 | 作用 | 常见模式 |
创建型(Creational) | 如何创建对象 | 单例、工厂、建造者、原型 |
结构型(Structural) | 如何组合类或对象 | 适配器、装饰器、代理、组合 |
行为型(Behavioral) | 对象间如何通信 | 观察者、策略、命令、状态 |
三、创建型模式(Creational Patterns)
1. 单例模式(Singleton)
确保一个类只有一个实例,并提供全局访问点。
应用场景:
- 数据库连接池
- 日志记录器
- 配置管理器
Python 实现方式:
方式一:使用 __new__
class Singleton:_instance = Nonedef __new__(cls):if cls._instance is None:cls._instance = super().__new__(cls)return cls._instancedef __init__(self):# 避免重复初始化if not hasattr(self, 'initialized'):self.data = {}self.initialized = True# 测试
s1 = Singleton()
s2 = Singleton()
print(s1 is s2) # True
方式二:使用装饰器(更 Pythonic)
def singleton(cls):instances = {}def get_instance(*args, **kwargs):if cls not in instances:instances[cls] = cls(*args, **kwargs)return instances[cls]return get_instance@singleton
class Database:def __init__(self):print("初始化数据库连接")db1 = Database()
db2 = Database()
print(db1 is db2) # True
2. 工厂模式(Factory Pattern)
定义一个用于创建对象的接口,但让子类决定实例化哪个类。
应用场景:
- 根据配置创建不同类型的对象
- 解耦对象创建与使用
简单工厂模式:
class Dog:def speak(self): return "汪汪"class Cat:def speak(self): return "喵喵"class AnimalFactory:@staticmethoddef create_animal(animal_type):if animal_type == "dog":return Dog()elif animal_type == "cat":return Cat()else:raise ValueError(f"未知动物类型: {animal_type}")# 使用
animal = AnimalFactory.create_animal("dog")
print(animal.speak()) # 汪汪
工厂方法模式:
from abc import ABC, abstractmethodclass Animal(ABC):@abstractmethoddef speak(self): passclass Dog(Animal):def speak(self): return "汪汪"class Cat(Animal):def speak(self): return "喵喵"class AnimalFactory(ABC):@abstractmethoddef create_animal(self) -> Animal: passclass DogFactory(AnimalFactory):def create_animal(self): return Dog()class CatFactory(AnimalFactory):def create_animal(self): return Cat()# 使用
factory = DogFactory()
dog = factory.create_animal()
print(dog.speak()) # 汪汪
3. 建造者模式(Builder Pattern)
将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。
应用场景:
- 构造复杂对象(如 HTML 文档、SQL 查询)
- 避免构造函数参数过多
class Pizza:def __init__(self):self.crust = ""self.toppings = []self.cheese = Falsedef __str__(self):return f"披萨: {self.crust}皮, {self.toppings}, {'有' if self.cheese else '无'}芝士"class PizzaBuilder:def __init__(self):self.pizza = Pizza()def set_crust(self, crust):self.pizza.crust = crustreturn self # 支持链式调用def add_topping(self, topping):self.pizza.toppings.append(topping)return selfdef with_cheese(self, cheese=True):self.pizza.cheese = cheesereturn selfdef build(self):return self.pizza# 使用
pizza = (PizzaBuilder().set_crust("薄").add_topping("蘑菇").add_topping("火腿").with_cheese().build())print(pizza) # 披萨: 薄皮, ['蘑菇', '火腿'], 有芝士
四、结构型模式(Structural Patterns)
1. 装饰器模式(Decorator Pattern)
动态地给一个对象添加一些额外的职责,而不改变其结构。
✅ Python 的 @decorator
语法正是此模式的体现。
class Coffee:def cost(self): return 10def description(self): return "咖啡"class MilkDecorator:def __init__(self, coffee):self._coffee = coffeedef cost(self):return self._coffee.cost() + 2def description(self):return self._coffee.description() + ", 牛奶"class SugarDecorator:def __init__(self, coffee):self._coffee = coffeedef cost(self):return self._coffee.cost() + 1def description(self):return self._coffee.description() + ", 糖"# 使用
simple_coffee = Coffee()
milk_coffee = MilkDecorator(simple_coffee)
sweet_coffee = SugarDecorator(milk_coffee)print(f"{sweet_coffee.description()}: ¥{sweet_coffee.cost()}")
# 咖啡, 牛奶, 糖: ¥13
2. 适配器模式(Adapter Pattern)
将一个类的接口转换成客户希望的另一个接口,使原本不兼容的类可以一起工作。
应用场景:
- 集成第三方库
- 旧系统接口兼容
class EuropeanSocket:def provide_power(self): return "提供 220V 交流电"class USSocket:def plug_in(self): return "插入 110V 插座"class SocketAdapter:def __init__(self, us_socket):self.us_socket = us_socketdef provide_power(self):# 适配:将 US 插座转换为欧洲插座接口power = self.us_socket.plug_in()return f"{power} → 转换为 220V"# 使用
us_socket = USSocket()
adapter = SocketAdapter(us_socket)
european_power = adapter.provide_power()
print(european_power) # 插入 110V 插座 → 转换为 220V
3. 代理模式(Proxy Pattern)
为其他对象提供一种代理,以控制对这个对象的访问。
应用场景:
- 延迟初始化(懒加载)
- 访问控制
- 日志记录
class RealImage:def __init__(self, filename):self.filename = filenameself.load_from_disk()def load_from_disk(self):print(f"从磁盘加载图像: {self.filename}")def display(self):print(f"显示图像: {self.filename}")class ImageProxy:def __init__(self, filename):self.filename = filenameself.real_image = Nonedef display(self):if self.real_image is None:self.real_image = RealImage(self.filename)self.real_image.display()# 使用
image = ImageProxy("photo.jpg")
# 此时未加载图像
image.display() # 第一次调用时才加载并显示
image.display() # 后续调用直接显示
五、行为型模式(Behavioral Patterns)
1. 观察者模式(Observer Pattern)
定义对象间的一对多依赖关系,当一个对象状态改变时,所有依赖者都会收到通知。
应用场景:
- 事件处理系统
- 消息订阅
- MVC 架构中的视图更新
class Subject:def __init__(self):self._observers = []def attach(self, observer):self._observers.append(observer)def detach(self, observer):self._observers.remove(observer)def notify(self, message):for observer in self._observers:observer.update(message)class Observer:def update(self, message):passclass EmailNotifier(Observer):def update(self, message):print(f"📧 发送邮件通知: {message}")class SMSNotifier(Observer):def update(self, message):print(f"📱 发送短信通知: {message}")# 使用
subject = Subject()
subject.attach(EmailNotifier())
subject.attach(SMSNotifier())subject.notify("订单已发货")
# 输出:
# 📧 发送邮件通知: 订单已发货
# 📱 发送短信通知: 订单已发货
2. 策略模式(Strategy Pattern)
定义一系列算法,将每个算法封装起来,并使它们可以互换。
应用场景:
- 支付方式选择
- 排序算法切换
- 缓存策略
from abc import ABC, abstractmethodclass PaymentStrategy(ABC):@abstractmethoddef pay(self, amount): passclass CreditCardPayment(PaymentStrategy):def pay(self, amount):print(f"使用信用卡支付 ¥{amount}")class AlipayPayment(PaymentStrategy):def pay(self, amount):print(f"使用支付宝支付 ¥{amount}")class PaymentContext:def __init__(self, strategy: PaymentStrategy):self._strategy = strategydef set_strategy(self, strategy: PaymentStrategy):self._strategy = strategydef execute_payment(self, amount):self._strategy.pay(amount)# 使用
payment = PaymentContext(CreditCardPayment())
payment.execute_payment(100) # 使用信用卡支付 ¥100payment.set_strategy(AlipayPayment())
payment.execute_payment(50) # 使用支付宝支付 ¥50
3. 状态模式(State Pattern)
允许对象在其内部状态改变时改变其行为。
应用场景:
- 订单状态流转
- 游戏角色状态
- 工作流引擎
class OrderState:def next_state(self, order): passdef prev_state(self, order): passdef print_status(self): passclass OrderedState(OrderState):def next_state(self, order):order.state = ShippedState()def print_status(self):return "已下单"class ShippedState(OrderState):def next_state(self, order):order.state = DeliveredState()def prev_state(self, order):order.state = OrderedState()def print_status(self):return "已发货"class DeliveredState(OrderState):def prev_state(self, order):order.state = ShippedState()def print_status(self):return "已送达"class Order:def __init__(self):self.state = OrderedState()def next(self):self.state.next_state(self)def prev(self):self.state.prev_state(self)def print_status(self):return self.state.print_status()# 使用
order = Order()
print(order.print_status()) # 已下单
order.next()
print(order.print_status()) # 已发货
order.next()
print(order.print_status()) # 已送达
order.prev()
print(order.print_status()) # 已发货
六、总结:设计模式核心要点
模式 | 核心思想 | 适用场景 |
单例 | 唯一实例 | 全局配置、连接池 |
工厂 | 解耦创建 | 多类型对象创建 |
建造者 | 分步构建 | 复杂对象构造 |
装饰器 | 动态增强 | 功能扩展(日志、缓存) |
适配器 | 接口转换 | 集成不兼容接口 |
代理 | 控制访问 | 懒加载、权限控制 |
观察者 | 发布-订阅 | 事件通知系统 |
策略 | 算法封装 | 可切换的业务逻辑 |
状态 | 行为随状态变 | 状态机、流程控制 |
七、学习建议
- 理解思想,而非死记代码:设计模式是解决问题的思路。
- 不要过度设计:简单问题用简单方案。
- 多阅读优秀源码:如 Django、Flask、Requests 中的设计模式应用。
- 实践驱动学习:在项目中尝试使用合适的模式。
📌 动手练习:
- 实现一个简单的“音乐播放器”,使用状态模式管理播放/暂停/停止状态。
- 使用策略模式实现一个支持多种排序算法(冒泡、快速、归并)的排序器。
- 创建一个“新闻发布系统”,使用观察者模式通知订阅用户。
class SortStrategy:def sort(self, data): passclass BubbleSort(SortStrategy):def sort(self, data):# 简化实现return sorted(data) # 实际应实现冒泡排序class QuickSort(SortStrategy):def sort(self, data):return sorted(data, reverse=True) # 简化class Sorter:def __init__(self, strategy: SortStrategy):self.strategy = strategydef set_strategy(self, strategy):self.strategy = strategydef sort(self, data):return self.strategy.sort(data)