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

Python设计模式终极指南:18种模式详解+正反案例对比+框架源码剖析

下面我将全面解析18种Python设计模式,每种模式都包含实际应用场景、优缺点分析、框架引用案例、可运行代码示例以及正反案例对比,帮助您深入理解设计模式的价值。

一、创建型模式(5种)

1. 单例模式(Singleton)

场景:数据库连接池、全局配置管理
优点:资源复用,保证全局一致性
缺点:违反单一职责,多线程需同步
框架应用:Django配置对象 django.conf.settings

class DatabaseConnection:_instance = Nonedef __new__(cls):if not cls._instance:cls._instance = super().__new__(cls)# 模拟数据库连接初始化print("创建新的数据库连接(昂贵操作)")return cls._instance# 正面示例
db1 = DatabaseConnection()
db2 = DatabaseConnection()
print(db1 is db2)  # True,复用同一连接# 反面示例(无单例)
class BadDatabase:def __init__(self):print("创建新的数据库连接(昂贵操作)")db3 = BadDatabase()
db4 = BadDatabase()  # 重复创建连接,浪费资源

2. 工厂方法模式(Factory Method)

场景:支付网关切换、日志处理器选择
优点:解耦客户端和具体类
缺点:增加代码复杂度

from abc import ABC, abstractmethodclass PaymentGateway(ABC):@abstractmethoddef pay(self, amount): passclass StripeGateway(PaymentGateway):def pay(self, amount): print(f"Stripe支付 ${amount}")class PayPalGateway(PaymentGateway):def pay(self, amount): print(f"PayPal支付 ${amount}")def payment_factory(gateway_type):if gateway_type == "stripe": return StripeGateway()if gateway_type == "paypal": return PayPalGateway()raise ValueError("无效支付网关")# 正面示例
payment = payment_factory("stripe")
payment.pay(100)  # 客户端无需知道具体实现类# 反面示例(硬编码依赖)
class OrderProcessor:def process_payment(self, amount):gateway = StripeGateway()  # 直接依赖具体类gateway.pay(amount)# 更换支付网关需修改源码

3. 抽象工厂模式(Abstract Factory)

场景:跨平台UI组件库
优点:确保产品兼容性
缺点:扩展新产品困难

class Button(ABC):@abstractmethoddef render(self): passclass WindowsButton(Button):def render(self): print("Windows风格按钮")class MacButton(Button):def render(self): print("Mac风格按钮")class GUIFactory(ABC):@abstractmethoddef create_button(self): passclass WindowsFactory(GUIFactory):def create_button(self): return WindowsButton()class MacFactory(GUIFactory):def create_button(self): return MacButton()# 正面示例
def create_ui(os_type):factory = WindowsFactory() if os_type == "windows" else MacFactory()button = factory.create_button()button.render()  # 自动匹配操作系统风格# 反面示例(平台相关代码分散)
if os_type == "windows":button = WindowsButton()
elif os_type == "mac":button = MacButton()
button.render()
# 添加新平台需修改多处条件判断

4. 建造者模式(Builder)

场景:复杂对象创建(如SQL查询)
优点:分离构造过程与表示
缺点:增加额外Builder类


class SQLQuery:def __init__(self):self.table = ""self.fields = []self.where_clauses = []def execute(self):fields = ", ".join(self.fields) or "*"where = (" WHERE " + " AND ".join(self.where_clauses)) if self.where_clauses else ""print(f"SELECT {fields} FROM {self.table}{where}")class QueryBuilder:def __init__(self):self.query = SQLQuery()def select(self, *fields):self.query.fields = fieldsreturn selfdef from_table(self, table):self.query.table = tablereturn selfdef where(self, condition):self.query.where_clauses.append(condition)return selfdef build(self):return self.query# 正面示例
query = (QueryBuilder().select("id", "name").from_table("users").where("age > 18").build())
query.execute()# 反面示例(构造参数爆炸)
class BadQuery:def __init__(self, table, fields=None, where=None, joins=None, group_by=None):# 参数过多难以维护self.table = tableself.fields = fields or []self.where = where or []# ...更多参数

5. 原型模式(Prototype)

场景:游戏对象克隆、配置模板
优点:避免重复初始化开销
缺点:深拷贝可能复杂


import copyclass NPC:def __init__(self, name, health, position):self.name = nameself.health = healthself.position = position# 模拟昂贵初始化print(f"创建NPC {name}(耗时操作)")def clone(self):return copy.deepcopy(self)# 正面示例
orc_template = NPC("兽人", 100, (0, 0))
orc1 = orc_template.clone()  # 快速克隆
orc1.position = (10, 5)# 反面示例(重复初始化)
orc2 = NPC("兽人", 100, (0, 0))  # 重复执行昂贵初始化

二、结构型模式(6种)

6. 适配器模式(Adapter)

场景:整合第三方库、旧系统接口改造
优点:解决接口不兼容问题
缺点:增加额外层


class LegacyLogger:def log_message(self, msg, priority):print(f"[{priority}] {msg}")class ModernLogger:def log(self, message, level="INFO"):print(f"{level}: {message}")class LoggerAdapter:def __init__(self, logger):self.logger = loggerdef log(self, message, level="INFO"):if isinstance(self.logger, LegacyLogger):# 转换接口priority = 1 if level == "ERROR" else 0self.logger.log_message(message, priority)else:self.logger.log(message, level)# 正面示例
legacy = LoggerAdapter(LegacyLogger())
legacy.log("系统错误", level="ERROR")  # 自动转换接口# 反面示例(直接修改第三方库)
# 修改LegacyLogger源码使其兼容ModernLogger接口 → 违反开闭原则

7. 装饰器模式(Decorator)

场景:功能扩展(日志、缓存、权限)
优点:动态添加功能,符合开闭原则
缺点:多层装饰可读性下降
框架应用:Flask路由装饰器 @app.route


def log_execution(func):def wrapper(*args, **kwargs):print(f"执行: {func.__name__}")return func(*args, **kwargs)return wrapperdef cache_result(func):cache = {}def wrapper(*args):if args in cache:print("返回缓存结果")return cache[args]result = func(*args)cache[args] = resultreturn resultreturn wrapper@log_execution
@cache_result
def fibonacci(n):if n <= 1: return nreturn fibonacci(n-1) + fibonacci(n-2)# 正面示例
print(fibonacci(10))  # 带日志和缓存# 反面示例(硬编码功能)
def bad_fibonacci(n):print(f"执行: bad_fibonacci")  # 日志硬编码# ...实现+缓存逻辑混合...

8. 代理模式(Proxy)

场景:延迟加载、访问控制
优点:控制对象访问,实现懒加载
缺点:增加响应时间


class HighResImage:def __init__(self, filename):self.filename = filenameself._load_image()def _load_image(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 not self._real_image:self._real_image = HighResImage(self.filename)self._real_image.display()# 正面示例
gallery = [ImageProxy(f"image{i}.jpg") for i in range(3)]
gallery[0].display()  # 仅加载第一张# 反面示例(提前加载所有资源)
images = [HighResImage(f"image{i}.jpg") for i in range(3)]  # 启动时全部加载

9. 外观模式(Facade)

场景:简化复杂子系统调用
优点:提供统一接口,降低耦合
缺点:可能成为"上帝对象"


class CPU:def process(self): print("CPU处理数据")class Memory:def load(self): print("内存加载数据")class HardDrive:def read(self): print("硬盘读取数据")class Computer:def __init__(self):self.cpu = CPU()self.memory = Memory()self.hd = HardDrive()def start(self):self.hd.read()self.memory.load()self.cpu.process()# 正面示例
pc = Computer()
pc.start()  # 简单调用接口# 反面示例(客户端直接调用子系统)
hd = HardDrive()
mem = Memory()
cpu = CPU()
hd.read()
mem.load()
cpu.process()  # 客户端需了解所有细节

10. 享元模式(Flyweight)

场景:文本编辑器字符格式
优点:大幅减少内存使用
缺点:增加代码复杂度


class CharacterStyle:_cache = {}def __new__(cls, font, size, color):key = (font, size, color)if key not in cls._cache:cls._cache[key] = super().__new__(cls)cls._cache[key].font = fontcls._cache[key].size = sizecls._cache[key].color = colorreturn cls._cache[key]class Document:def __init__(self):self.chars = []def add_char(self, char, font, size, color):style = CharacterStyle(font, size, color)self.chars.append((char, style))def render(self):for char, style in self.chars:print(f"渲染 '{char}' 使用 {style.font}")# 正面示例(1000个字符只创建2种样式)
doc = Document()
for _ in range(500):doc.add_char('A', "Arial", 12, "black")
for _ in range(500):doc.add_char('B', "Times", 14, "blue")
print(f"样式实例数: {len(CharacterStyle._cache)}")  # 2# 反面示例(重复创建样式)
class BadChar:def __init__(self, char, font, size, color):self.char = charself.font = font# 每个字符独立存储样式 → 内存浪费

三、行为型模式(7种)

11. 观察者模式(Observer)

场景:事件通知、消息订阅
优点:解耦发布者和订阅者
缺点:意外更新链
框架应用:Django Signals


class Newsletter:def __init__(self):self.subscribers = []def subscribe(self, subscriber):self.subscribers.append(subscriber)def unsubscribe(self, subscriber):self.subscribers.remove(subscriber)def publish(self, news):print(f"发布新闻: {news}")for sub in self.subscribers:sub.notify(news)class Subscriber:def notify(self, news):print(f"{self.name} 收到: {news}")class EmailSubscriber(Subscriber):def __init__(self, name):self.name = f"邮箱用户-{name}"class AppSubscriber(Subscriber):def __init__(self, name):self.name = f"APP用户-{name}"# 正面示例
newsletter = Newsletter()
newsletter.subscribe(EmailSubscriber("张三"))
newsletter.subscribe(AppSubscriber("李四"))
newsletter.publish("Python 3.12发布")# 反面示例(紧耦合)
class BadNewsletter:def publish(self, news):print(f"发布新闻: {news}")# 直接调用具体方法EmailSubscriber("张三").notify(news)AppSubscriber("李四").notify(news)

12. 策略模式(Strategy)

场景:支付方式选择、排序算法
优点:运行时切换算法
缺点:客户端需了解不同策略


class CompressionStrategy(ABC):@abstractmethoddef compress(self, file): passclass ZipStrategy(CompressionStrategy):def compress(self, file):print(f"ZIP压缩 {file}(压缩率高)")class RarStrategy(CompressionStrategy):def compress(self, file):print(f"RAR压缩 {file}(加密支持)")class Compressor:def __init__(self, strategy=None):self.strategy = strategy or ZipStrategy()def set_strategy(self, strategy):self.strategy = strategydef compress_file(self, file):self.strategy.compress(file)# 正面示例
compressor = Compressor()
compressor.compress_file("data.txt")compressor.set_strategy(RarStrategy())
compressor.compress_file("data.txt")  # 动态切换算法# 反面示例(条件分支判断)
class BadCompressor:def compress(self, file, method="zip"):if method == "zip":print(f"ZIP压缩 {file}")elif method == "rar":print(f"RAR压缩 {file}")# 添加新算法需修改源码

13. 模板方法模式(Template Method)

场景:算法框架定义
优点:代码复用,扩展性好
缺点:可能限制灵活性
框架应用:Django类视图 View.dispatch()


class ReportGenerator(ABC):def generate(self):self.collect_data()self.process_data()self.export()@abstractmethoddef collect_data(self): passdef process_data(self):print("通用数据处理")@abstractmethoddef export(self): passclass PDFReport(ReportGenerator):def collect_data(self):print("收集PDF数据")def export(self):print("导出PDF文档")class ExcelReport(ReportGenerator):def collect_data(self):print("收集Excel数据")def process_data(self):print("自定义Excel数据处理")def export(self):print("导出Excel文件")# 正面示例
pdf = PDFReport()
pdf.generate()  # 复用通用流程# 反面示例(重复代码)
class BadPDFReport:def generate(self):print("收集PDF数据")print("通用数据处理")  # 重复代码print("导出PDF文档")class BadExcelReport:def generate(self):print("收集Excel数据")print("通用数据处理")  # 重复代码print("导出Excel文件")

14. 责任链模式(Chain of Responsibility)

场景:请求处理管道、中间件
优点:动态添加处理者
缺点:请求可能未处理
框架应用:Django中间件系统


class Handler(ABC):def __init__(self, successor=None):self.successor = successordef handle(self, request):if self.can_handle(request):return self.process(request)elif self.successor:return self.successor.handle(request)raise Exception("无法处理请求")@abstractmethoddef can_handle(self, request): pass@abstractmethoddef process(self, request): passclass AuthHandler(Handler):def can_handle(self, request):return "auth" in requestdef process(self, request):print("身份验证通过")class LogHandler(Handler):def can_handle(self, request):return True  # 最终处理器def process(self, request):print(f"记录请求: {request}")# 正面示例
pipeline = AuthHandler(LogHandler())
pipeline.handle({"action": "login", "auth": "token"})# 反面示例(巨型处理函数)
def bad_handler(request):if "auth" in request:print("身份验证通过")# ...其他条件分支...print(f"记录请求: {request}")  # 所有逻辑耦合

15. 命令模式(Command)

场景:GUI操作、事务管理
优点:解耦调用者和接收者
缺点:增加命令类数量


class Light:def on(self): print("开灯")def off(self): print("关灯")class Command(ABC):@abstractmethoddef execute(self): passclass LightOnCommand(Command):def __init__(self, light):self.light = lightdef execute(self):self.light.on()class LightOffCommand(Command):def __init__(self, light):self.light = lightdef execute(self):self.light.off()class RemoteControl:def __init__(self):self.history = []def execute_command(self, command):command.execute()self.history.append(command)def undo(self):if self.history:last = self.history.pop()print("撤销操作: ", end="")last.execute()  # 简化:实际需实现反向操作# 正面示例
light = Light()
remote = RemoteControl()
remote.execute_command(LightOnCommand(light))
remote.undo()  # 支持撤销# 反面示例(直接调用)
light.on()  # 无法记录历史,不支持撤销

16. 状态模式(State)

场景:订单状态流转、游戏角色状态
优点:简化状态转换逻辑
缺点:增加状态类数量


class OrderState(ABC):@abstractmethoddef next(self, order): pass@abstractmethoddef prev(self, order): passclass PendingState(OrderState):def next(self, order):order.state = PaidState()def prev(self, order):print("已是初始状态")class PaidState(OrderState):def next(self, order):order.state = ShippedState()def prev(self, order):order.state = PendingState()class Order:def __init__(self):self.state = PendingState()def next_state(self):print("转到下一状态")self.state.next(self)def __str__(self):return type(self.state).__name__# 正面示例
order = Order()
print(order)  # PendingState
order.next_state()
print(order)  # PaidState# 反面示例(状态标志+条件分支)
class BadOrder:def __init__(self):self.status = "pending"def next_state(self):if self.status == "pending":self.status = "paid"elif self.status == "paid":self.status = "shipped"# 状态逻辑分散在各处

四、Python设计模式深度洞察

1.动态语言特性:Python的鸭子类型减少了对工厂模式的需求2.装饰器内置支持:@decorator语法是装饰器模式的语法糖3.模式混合使用:实际项目中常组合多种模式(如Observer + Command)4.框架设计启示:Django使用Template Method定义视图生命周期Flask通过Decorator实现路由注册SQLAlchemy的Session使用Proxy模式

五、为什么需要设计模式?—— 未使用模式的代价

问题场景无模式方案后果适用模式
全局配置管理多个独立配置对象配置不一致,资源浪费单例模式
多支付网关支持if/else硬编码添加新网关需修改核心逻辑策略模式
跨平台UI开发平台相关代码分散维护困难,兼容性问题抽象工厂
复杂对象构造超长构造函数参数混乱,构造逻辑复杂建造者模式
事件通知系统直接调用接收方紧耦合,难以扩展新接收方观察者模式

相关文章:

  • Gradle打包流程
  • 129. 求根节点到叶节点数字之和 --- DFS +回溯(js)
  • 优化TCP/IP协议栈与网络层
  • Redis 持久化机制详解:RDB、AOF 原理与面试最佳实践(AOF篇)
  • MO+内核32位单片机的PY32F030单片机开发板
  • Gazebo 仿真环境系列教程(二):在 Gazebo 中构建自己的机器人
  • Spring MVC详解
  • Leetcode hot100 Java刷题
  • Loggers 配置解析(log4j.xml)
  • Vue3 + Axios + Ant Design Vue 请求封装详解教程(含 Token 鉴权、加密、下载)
  • 经典俄罗斯方块微信小游戏流量主小程序开源
  • Vue.js 计算属性详解:核心概念、最佳实践与注意事项
  • 宇鹿家政服务系统小程序ThinkPHP+UniApp
  • 责任链模式详解
  • 音视频之H.264视频编码传输及其在移动通信中的应用
  • [AJAX 实战] 图书管理系统下 编辑图书
  • 锌锭工业相机:迁移科技驱动金属制造自动化新高度
  • CppCon 2017 学习:Everything You Ever Wanted to Know about DLLs
  • 打破物理桎梏:CAN-ETH网关如何用UDP封装重构工业网络边界
  • 破局基建困局:国有平台公司数字化转型的生态重构
  • 广东党员两学一做考试网站/我要发布信息
  • 做微信公众平台的网站吗/软文文章
  • javascript怎么读/充电宝关键词优化
  • 忻州网站建设公司/宁波免费seo排名优化
  • 天津网站建设基本流程/十大短视频平台排行榜
  • wordpress获取当前页面链接/网站排名优化方案