当前位置: 首页 > news >正文

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())  # 已发货

六、总结:设计模式核心要点

模式

核心思想

适用场景

单例

唯一实例

全局配置、连接池

工厂

解耦创建

多类型对象创建

建造者

分步构建

复杂对象构造

装饰器

动态增强

功能扩展(日志、缓存)

适配器

接口转换

集成不兼容接口

代理

控制访问

懒加载、权限控制

观察者

发布-订阅

事件通知系统

策略

算法封装

可切换的业务逻辑

状态

行为随状态变

状态机、流程控制


七、学习建议

  1. 理解思想,而非死记代码:设计模式是解决问题的思路。
  2. 不要过度设计:简单问题用简单方案。
  3. 多阅读优秀源码:如 Django、Flask、Requests 中的设计模式应用。
  4. 实践驱动学习:在项目中尝试使用合适的模式。

📌 动手练习

  1. 实现一个简单的“音乐播放器”,使用状态模式管理播放/暂停/停止状态。
  2. 使用策略模式实现一个支持多种排序算法(冒泡、快速、归并)的排序器。
  3. 创建一个“新闻发布系统”,使用观察者模式通知订阅用户。
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)
http://www.dtcms.com/a/336345.html

相关文章:

  • PWM输入捕获(测量按键按下时间、测量PWM波)
  • 25. 能否创建一个包含可变对象的不可变对象
  • YOLOV5训练自己的数据集并用自己的数据集检测
  • 2025-08-17 李沐深度学习16——目标检测
  • PAT 1068 Find More Coins
  • ACPI TABLE 方式加载device driver--以spi controller为例
  • 认识信号量机制、以及用信号量来实现进程互斥于进程同步
  • 计算机网络 TCP time_wait 状态 详解
  • VirtualBox-4.3.10-93012-Win.exe 安装教程附详细步骤(附安装包下载)
  • 为何她总在关键时“失联”?—— 解密 TCP 连接异常中断
  • TensorRT-LLM.V1.1.0rc1:Dockerfile.multi文件解读
  • LeetCode 刷题【44. 通配符匹配】
  • 多墨智能-AI一键生成工作文档/流程图/思维导图
  • 《WINDOWS 环境下32位汇编语言程序设计》第3章 使用MASM
  • Redis面试精讲 Day 23:Redis与数据库数据一致性保障
  • 什么是回表?
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘scikit-image’问题
  • Hooks useState的使用
  • leetcode热题100——day33
  • 视频内容提取与AI总结:提升学习效率的实用方法
  • 【深度学习新浪潮】近三年图像处理领域无监督学习的研究进展一览
  • 科目二的四个电路
  • 《Vuejs设计与实现》第 14 章(内建组件和模块)
  • 概率dp|math
  • Android中切换语言的方法
  • 基于Netty的高并发WebSocket连接管理与性能优化实践指南
  • ReactNode 类型
  • 第12章《学以致用》—PowerShell 自学闭环与实战笔记
  • “让机器人更智慧 让具身体更智能”北京世界机器人大会行业洞察
  • Python 调试工具的高级用法