嘿,咱们的Python学习搭子又来啦!前面咱们一起深入剖析了Flask和Django的框架原理,是不是感觉对Web开发有了更底层的理解?接下来咱们要进入一个新阶段——系统设计模式实战。
- 2. 掌握6种常用设计模式的核心思想和Python实现
你可能听过这样的说法:“设计模式是解决特定问题的通用方案”。这句话没错,但我觉得更生动的理解是:
设计模式就像是烹饪中的“经典菜谱”,记录了无数厨师在实践中验证过的最佳做法,当你遇到相似场景时,可以直接参考,避免重复发明轮子。
在软件开发中,设计模式最早由“四人帮”(GoF)在1994年提出,总结了23种经典模式。不过别担心,咱们不需要全部掌握,咱们今天重点学习Python Web开发中最实用的那几种。
# 初级实现:硬编码支付逻辑defprocess_order(order):if order.payment_method == 'alipay':# 支付宝处理逻辑(100行代码)return process_alipay(order)elif order.payment_method == 'wechat':# 微信支付处理逻辑(80行代码)return process_wechat(order)elif order.payment_method == 'credit_card':# 信用卡处理逻辑(120行代码)return process_credit_card(order)# 每增加一个支付方式,就要修改这个函数
- 1. 违反开闭原则:每次新增支付方式都要修改核心代码
# 使用策略模式后的优雅实现defprocess_order(order): payment_strategy = PaymentStrategyFactory.create(order.payment_method)return payment_strategy.process(order)
在深入学习具体模式前,咱们先记住几个Pythonic的设计原则:
- 1. 简洁优于复杂:能用简单函数解决的问题,就不要用复杂的类层次
- 2. 鸭子类型优先:Python的动态特性让接口定义更灵活
- 3. 可读性至上:代码是给人看的,其次才是机器执行
- 4. 实用主义:选择最适合当前场景的解决方案,不必追求“完美设计”
好了,理论铺垫得差不多了,接下来咱们进入实战环节!
MVC(Model-View-Controller)可能是你最熟悉的设计模式,它虽然不是GoF的23种模式之一,但在Web开发中几乎是标配。
- • Controller(控制器):负责接收用户输入,协调Model和View
# 一个极简的MVC实现classUserModel:"""模型:用户数据管理"""def__init__(self):self.users = {}defadd_user(self, user_id, user_info):self.users[user_id] = user_inforeturn user_infodefget_user(self, user_id):returnself.users.get(user_id)classUserView:"""视图:用户信息展示""" @staticmethoddefdisplay_user(user_info):if user_info:print(f"用户名:{user_info['name']}")print(f"邮箱:{user_info['email']}")print(f"注册时间:{user_info['created_at']}")else:print("用户不存在")classUserController:"""控制器:处理用户请求"""def__init__(self):self.model = UserModel()self.view = UserView()defcreate_user(self, user_id, name, email): user_info = {'name': name,'email': email,'created_at': datetime.now().isoformat() } result = self.model.add_user(user_id, user_info)self.view.display_user(result)return resultdefshow_user(self, user_id): user_info = self.model.get_user(user_id)self.view.display_user(user_info)# 使用示例controller = UserController()controller.create_user(1, "张三", "zhangsan@example.com")controller.show_user(1)
- • Django:典型的MVC架构(虽然他们自称MTV)
- • Controller:Django框架本身的路由系统
- • 常用模式:蓝本(Blueprint)+ SQLAlchemy + Jinja2模板
2.2 Repository模式:数据访问的抽象层
Repository模式在领域驱动设计(DDD)中很常见,它为数据访问提供了一层抽象,让业务逻辑不依赖于具体的数据存储方式。
想象一下,你的电商系统开始用MySQL,后来要部分迁移到MongoDB。如果没有Repository,你就要到处修改数据库查询代码。
from abc import ABC, abstractmethodfrom typing importList, OptionalclassUser:"""领域实体:用户"""def__init__(self, id: int, name: str, email: str):self.id = idself.name = nameself.email = emailclassUserRepository(ABC):"""仓储接口:定义数据访问契约""" @abstractmethoddefadd(self, user: User) -> User:pass @abstractmethoddefget(self, user_id: int) -> Optional[User]:pass @abstractmethoddeffind_by_email(self, email: str) -> Optional[User]:pass @abstractmethoddeflist_all(self) -> List[User]:passclassMySQLUserRepository(UserRepository):"""MySQL实现"""def__init__(self, db_connection):self.db = db_connectiondefadd(self, user: User) -> User:# 实际的SQL插入逻辑 cursor = self.db.cursor() cursor.execute("INSERT INTO users (id, name, email) VALUES (%s, %s, %s)", (user.id, user.name, user.email) )self.db.commit()return userdefget(self, user_id: int) -> Optional[User]: cursor = self.db.cursor() cursor.execute("SELECT id, name, email FROM users WHERE id = %s", (user_id,)) row = cursor.fetchone()if row:return User(id=row[0], name=row[1], email=row[2])returnNone# 其他方法实现...classUserService:"""业务服务层:使用仓储接口"""def__init__(self, user_repository: UserRepository):self.repo = user_repositorydefregister_user(self, name: str, email: str) -> User:# 业务逻辑:检查邮箱是否已存在 existing_user = self.repo.find_by_email(email)if existing_user:raise ValueError(f"邮箱 {email} 已被注册")# 生成用户ID(实际项目中可能用UUID) user_id = self._generate_user_id() user = User(id=user_id, name=name, email=email)returnself.repo.add(user)def_generate_user_id(self) -> int:# 简单的ID生成逻辑import randomreturn random.randint(1000, 9999)# 使用示例:可以轻松切换数据源# repo = MySQLUserRepository(db_connection)# service = UserService(repo)# service.register_user("李四", "lisi@example.com")
- 1. 可测试性:业务逻辑测试时可以用内存仓储代替真实数据库
- 2. 可维护性:数据存储方式变更时,只需修改仓储实现
- 3. 可扩展性:轻松实现缓存层(装饰器模式+仓储模式)
工厂模式负责创建对象,而不是让客户端直接实例化具体类。这在需要根据条件创建不同类型对象时特别有用。
from enum import Enumfrom typing importUnionclassNotificationType(Enum):"""通知类型枚举""" EMAIL = "email" SMS = "sms" PUSH = "push" SLACK = "slack"classEmailNotification:"""邮件通知"""def__init__(self, recipient: str, message: str):self.recipient = recipientself.message = messagedefsend(self) -> bool:# 实际发送邮件的逻辑print(f"📧 发送邮件给 {self.recipient}: {self.message}")returnTrueclassSMSNotification:"""短信通知"""def__init__(self, recipient: str, message: str):self.recipient = recipientself.message = messagedefsend(self) -> bool:# 实际发送短信的逻辑print(f"📱 发送短信给 {self.recipient}: {self.message}")returnTrueclassPushNotification:"""推送通知"""def__init__(self, device_token: str, message: str):self.device_token = device_tokenself.message = messagedefsend(self) -> bool:# 实际推送的逻辑print(f"📲 推送到设备 {self.device_token}: {self.message}")returnTrue# 方案1:简单工厂函数(最Pythonic)defcreate_notification(notification_type: NotificationType, recipient: str, message: str) -> Union[EmailNotification, SMSNotification, PushNotification]:"""通知工厂函数"""if notification_type == NotificationType.EMAIL:return EmailNotification(recipient, message)elif notification_type == NotificationType.SMS:return SMSNotification(recipient, message)elif notification_type == NotificationType.PUSH:return PushNotification(recipient, message)elif notification_type == NotificationType.SLACK:# 未来可以轻松扩展raise NotImplementedError("Slack通知尚未实现")else:raise ValueError(f"不支持的通知类型: {notification_type}")# 方案2:工厂类+注册机制(更灵活)classNotificationFactory:"""可扩展的通知工厂"""def__init__(self):self._creators = {}defregister(self, notification_type: NotificationType, creator_func):"""注册通知类型创建器"""self._creators[notification_type] = creator_funcdefcreate(self, notification_type: NotificationType, *args, **kwargs):"""创建通知实例""" creator = self._creators.get(notification_type)ifnot creator:raise ValueError(f"未注册的通知类型: {notification_type}")return creator(*args, **kwargs)# 使用示例if __name__ == "__main__":# 使用简单工厂 email = create_notification(NotificationType.EMAIL, "user@example.com", "欢迎加入我们!") email.send()# 使用注册工厂 factory = NotificationFactory() factory.register(NotificationType.EMAIL, lambda r, m: EmailNotification(r, m)) factory.register(NotificationType.SMS,lambda r, m: SMSNotification(r, m)) sms = factory.create(NotificationType.SMS, "13800138000", "验证码:123456") sms.send()
from django import forms# Django内部使用工厂模式创建表单字段classContactForm(forms.Form):# 这些字段类实际上都是工厂函数 name = forms.CharField(max_length=100) email = forms.EmailField() message = forms.CharField(widget=forms.Textarea)
观察者模式定义了一对多的依赖关系,当一个对象状态改变时,所有依赖它的对象都会收到通知并自动更新。
- 1. Subject(主题):维护观察者列表,提供添加/删除观察者的方法
- 3. ConcreteObserver(具体观察者):实现更新逻辑
from abc import ABC, abstractmethodfrom typing importListclassOrderEvent:"""订单事件数据类"""def__init__(self, order_id: str, event_type: str, data: dict):self.order_id = order_idself.event_type = event_type # 'created', 'paid', 'shipped', 'completed'self.data = dataclassOrderObserver(ABC):"""订单观察者接口""" @abstractmethoddefupdate(self, event: OrderEvent):"""收到订单事件通知"""passclassEmailNotificationObserver(OrderObserver):"""邮件通知观察者"""defupdate(self, event: OrderEvent):if event.event_type == 'created':print(f"📧 发送订单创建邮件:订单 {event.order_id} 已创建")elif event.event_type == 'paid':print(f"📧 发送支付成功邮件:订单 {event.order_id} 已支付")elif event.event_type == 'shipped':print(f"📧 发送发货通知邮件:订单 {event.order_id} 已发货")classInventoryObserver(OrderObserver):"""库存观察者"""defupdate(self, event: OrderEvent):if event.event_type == 'paid':# 扣减库存逻辑print(f"📦 扣减库存:订单 {event.order_id} 包含商品 {event.data.get('items')}")elif event.event_type == 'cancelled':# 恢复库存逻辑print(f"📦 恢复库存:订单 {event.order_id} 已取消")classAnalyticsObserver(OrderObserver):"""数据分析观察者"""defupdate(self, event: OrderEvent):# 记录事件到分析系统print(f"📊 记录分析事件:{event.event_type} - 订单 {event.order_id}")classOrderSubject:"""订单主题(被观察者)"""def__init__(self):self._observers: List[OrderObserver] = []defattach(self, observer: OrderObserver):"""添加观察者"""if observer notinself._observers:self._observers.append(observer)defdetach(self, observer: OrderObserver):"""移除观察者"""if observer inself._observers:self._observers.remove(observer)defnotify(self, event: OrderEvent):"""通知所有观察者"""for observer inself._observers: observer.update(event)classOrderService:"""订单服务"""def__init__(self):self.subject = OrderSubject()defcreate_order(self, order_id: str, items: List[str], total_amount: float):"""创建订单"""# 业务逻辑...print(f"🛒 创建订单:{order_id}")# 创建事件并通知观察者 event = OrderEvent( order_id=order_id, event_type='created', data={'items': items, 'total_amount': total_amount} )self.subject.notify(event)return order_iddefpay_order(self, order_id: str):"""支付订单"""# 业务逻辑...print(f"💳 支付订单:{order_id}") event = OrderEvent( order_id=order_id, event_type='paid', data={'payment_time': '2024-02-25 10:30:00'} )self.subject.notify(event)# 使用示例if __name__ == "__main__":# 创建订单服务 order_service = OrderService()# 注册观察者 order_service.subject.attach(EmailNotificationObserver()) order_service.subject.attach(InventoryObserver()) order_service.subject.attach(AnalyticsObserver())# 创建订单(会自动通知所有观察者) order_id = order_service.create_order("ORD20240225001", ["iPhone 15", "AirPods"], 7999.00)# 支付订单 order_service.pay_order(order_id)
from django.db.models.signals import post_savefrom django.dispatch import receiverfrom django.contrib.auth.models import User@receiver(post_save, sender=User)defsend_welcome_email(sender, instance, created, **kwargs):"""新用户注册时发送欢迎邮件"""if created:print(f"欢迎新用户:{instance.username}")# 实际发送邮件逻辑
策略模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换。策略模式让算法的变化独立于使用算法的客户端。
# 传统面向对象实现from abc import ABC, abstractmethodclassPaymentStrategy(ABC):"""支付策略接口""" @abstractmethoddefpay(self, amount: float) -> str:passclassAlipayStrategy(PaymentStrategy):"""支付宝支付"""defpay(self, amount: float) -> str:# 实际调用支付宝APIreturnf"支付宝支付成功:{amount}元"classWechatPayStrategy(PaymentStrategy):"""微信支付"""defpay(self, amount: float) -> str:# 实际调用微信支付APIreturnf"微信支付成功:{amount}元"classCreditCardStrategy(PaymentStrategy):"""信用卡支付"""defpay(self, amount: float) -> str:# 实际处理信用卡支付returnf"信用卡支付成功:{amount}元"classPaymentContext:"""支付上下文"""def__init__(self, strategy: PaymentStrategy):self._strategy = strategydefset_strategy(self, strategy: PaymentStrategy):"""设置支付策略"""self._strategy = strategydefexecute_payment(self, amount: float) -> str:"""执行支付"""returnself._strategy.pay(amount)# 使用示例context = PaymentContext(AlipayStrategy())print(context.execute_payment(100.0)) # 支付宝支付成功:100.0元context.set_strategy(WechatPayStrategy())print(context.execute_payment(200.0)) # 微信支付成功:200.0元
# Pythonic实现:利用一等函数defalipay_pay(amount: float) -> str:"""支付宝支付函数"""returnf"支付宝支付成功:{amount}元"defwechat_pay(amount: float) -> str:"""微信支付函数"""returnf"微信支付成功:{amount}元"defcredit_card_pay(amount: float) -> str:"""信用卡支付函数"""returnf"信用卡支付成功:{amount}元"classPaymentContext:"""支付上下文(简化版)"""def__init__(self, pay_func):self.pay_func = pay_funcdefexecute_payment(self, amount: float) -> str:"""执行支付"""returnself.pay_func(amount)# 使用示例:更简洁context = PaymentContext(alipay_pay)print(context.execute_payment(100.0))# 动态切换策略context.pay_func = wechat_payprint(context.execute_payment(200.0))# 甚至可以直接用字典映射payment_strategies = {'alipay': alipay_pay,'wechat': wechat_pay,'credit_card': credit_card_pay,}# 根据用户选择执行user_choice = 'wechat'payment_func = payment_strategies[user_choice]print(payment_func(300.0))
- 2. 排序算法切换:根据数据量选择快速排序或归并排序
- 3. 数据导出格式:导出为JSON、CSV或Excel
装饰器模式可能是Python中最自然的设计模式,因为Python直接提供了语法支持!
# 传统装饰器模式实现classComponent(ABC): @abstractmethoddefoperation(self):passclassConcreteComponent(Component):defoperation(self):return"原始操作"classDecorator(Component):def__init__(self, component: Component):self._component = componentdefoperation(self):returnself._component.operation()classConcreteDecoratorA(Decorator):defoperation(self):returnf"装饰器A添加的行为 + {super().operation()}"# 使用component = ConcreteComponent()decorated = ConcreteDecoratorA(component)print(decorated.operation())
# Python装饰器函数deflog_decorator(func):"""日志装饰器"""defwrapper(*args, **kwargs):print(f"🚀 开始执行:{func.__name__}") result = func(*args, **kwargs)print(f"✅ 执行完成:{func.__name__}")return resultreturn wrapperdeftimer_decorator(func):"""计时装饰器"""import timedefwrapper(*args, **kwargs): start_time = time.time() result = func(*args, **kwargs) end_time = time.time()print(f"⏱️ 函数 {func.__name__} 执行耗时:{end_time - start_time:.4f}秒")return resultreturn wrapper# 使用装饰器@log_decorator@timer_decoratordefcomplex_calculation(n: int) -> int:"""模拟复杂计算"""import time time.sleep(0.5) # 模拟耗时操作returnsum(range(n))# 调用result = complex_calculation(1000)print(f"计算结果:{result}")
from flask import Flaskapp = Flask(__name__)@app.route('/') # 这是装饰器!defhome():return"欢迎首页"@app.route('/api/users')defget_users():return {"users": ["张三", "李四"]}@app.route('/api/orders/<int:order_id>')defget_order(order_id):return {"order_id": order_id, "status": "shipped"}
from django.contrib.auth.decorators import login_requiredfrom django.views.decorators.cache import cache_pagefrom django.views.decorators.csrf import csrf_exempt@login_required@cache_page(60 * 15) # 缓存15分钟defprofile_view(request):# 需要登录才能访问,且结果被缓存return render(request, 'profile.html')
classSingleton:"""单例模式装饰器(类装饰器版本)"""def__init__(self, cls):self._cls = clsself._instance = Nonedef__call__(self, *args, **kwargs):ifself._instance isNone:self._instance = self._cls(*args, **kwargs)returnself._instance@SingletonclassDatabaseConnection:def__init__(self):print("数据库连接已创建")defquery(self, sql):returnf"执行查询:{sql}"# 使用:多次实例化都返回同一个对象db1 = DatabaseConnection()db2 = DatabaseConnection()print(db1 is db2) # True
背景:一个中小型电商网站,订单处理逻辑分散在各个视图函数中,代码重复严重,新增功能困难。
# 重构后的订单系统核心代码classOrder:"""订单领域实体"""def__init__(self, order_id, items, total_amount):self.id = order_idself.items = itemsself.total_amount = total_amountself.status = 'created'classOrderRepository:"""订单仓储"""defsave(self, order):# 保存到数据库passdefget(self, order_id):# 从数据库获取passclassPaymentStrategy:"""支付策略接口"""defpay(self, order: Order) -> bool:passclassOrderService:"""订单服务(外观模式)"""def__init__(self, order_repo, payment_strategy, observers=None):self.repo = order_repoself.payment_strategy = payment_strategyself.subject = OrderSubject()# 注册观察者if observers:for observer in observers:self.subject.attach(observer)defcreate_order(self, items, total_amount) -> Order:"""创建订单(工厂方法)""" order_id = self._generate_order_id() order = Order(order_id, items, total_amount)# 保存订单self.repo.save(order)# 通知观察者 event = OrderEvent(order_id, 'created', {'items': items})self.subject.notify(event)return orderdefpay_order(self, order_id) -> bool:"""支付订单""" order = self.repo.get(order_id)# 使用策略模式进行支付 success = self.payment_strategy.pay(order)if success: order.status = 'paid'self.repo.save(order)# 通知观察者 event = OrderEvent(order_id, 'paid', {})self.subject.notify(event)returnTruereturnFalsedef_generate_order_id(self) -> str:import uuidreturnf"ORD_{uuid.uuid4().hex[:8].upper()}"
背景:一个企业级内容管理系统需要支持多种内容类型(文章、视频、产品),并且要允许第三方开发插件。
解决方案:装饰器模式 + 观察者模式 + 策略模式
# 插件系统的核心设计classContent:"""内容基类"""def__init__(self, title, body):self.title = titleself.body = bodyself.metadata = {}classContentProcessor(ABC):"""内容处理器接口""" @abstractmethoddefprocess(self, content: Content) -> Content:pass# 基础处理器classBaseProcessor(ContentProcessor):defprocess(self, content):# 基础处理逻辑 content.metadata['processed_at'] = datetime.now().isoformat()return content# 插件装饰器defplugin_decorator(plugin_func):"""插件装饰器:将普通函数转换为处理器插件"""classPluginProcessor(ContentProcessor):def__init__(self, inner_processor):self._inner = inner_processordefprocess(self, content):# 先执行内部处理器 content = self._inner.process(content)# 再执行插件逻辑return plugin_func(content)return PluginProcessor# 插件示例@plugin_decoratordefseo_optimization_plugin(content):"""SEO优化插件""" content.metadata['seo_title'] = f"{content.title} | 我的网站" content.metadata['seo_description'] = content.body[:150] + "..."return content@plugin_decorator defimage_optimization_plugin(content):"""图片优化插件"""# 自动压缩内容中的图片if'images'in content.body: content.metadata['images_optimized'] = Truereturn content# 插件管理器classPluginManager:def__init__(self):self.plugins = []self._observers = []defregister_plugin(self, plugin_processor_class):"""注册插件"""self.plugins.append(plugin_processor_class)# 通知观察者for observer inself._observers: observer.on_plugin_registered(plugin_processor_class)defcreate_processor_chain(self, base_processor):"""创建处理器链(责任链模式)""" processor = base_processorfor plugin_class inself.plugins: processor = plugin_class(processor)return processor# 使用示例if __name__ == "__main__":# 初始化 manager = PluginManager() manager.register_plugin(seo_optimization_plugin) manager.register_plugin(image_optimization_plugin)# 创建处理链 base_processor = BaseProcessor() processor_chain = manager.create_processor_chain(base_processor)# 处理内容 article = Content("Python设计模式", "设计模式是...") processed_article = processor_chain.process(article)print(f"处理后的元数据:{processed_article.metadata}")
- 1. 开闭原则:新增插件只需注册,无需修改现有代码
Django是一个设计模式应用的宝库,咱们来看几个典型例子:
from django.views import Viewfrom django.http import HttpResponseclassMyView(View):"""Django类视图:模板方法模式的典范"""defget(self, request, *args, **kwargs):# 子类实现具体逻辑return HttpResponse("GET请求")defpost(self, request, *args, **kwargs):return HttpResponse("POST请求")# dispatch方法是模板方法# 它定义了处理HTTP请求的算法骨架defdispatch(self, request, *args, **kwargs):# 前置处理(认证、权限检查等)print("请求预处理...")# 调用具体方法(由子类实现)if request.method.lower() inself.http_method_names: handler = getattr(self, request.method.lower(), self.http_method_not_allowed)else: handler = self.http_method_not_allowed# 后置处理 response = handler(request, *args, **kwargs)print("请求后处理...")return response
# Django的settings.py实际上是一个单例from django.conf import settings# 全局唯一配置对象print(settings.DEBUG) # 在整个应用中都是同一个实例print(settings.DATABASES)
Flask以其简洁和灵活著称,设计模式的使用也很巧妙:
from flask import Flask, requestfrom functools import wrapsapp = Flask(__name__)# Flask的核心:用装饰器注册路由@app.route('/')defindex():return'首页'# 自定义装饰器:权限控制defadmin_required(f): @wraps(f)defdecorated_function(*args, **kwargs):ifnot current_user.is_admin: abort(403)return f(*args, **kwargs)return decorated_function# 使用自定义装饰器@app.route('/admin')@admin_requireddefadmin_panel():return'管理面板'
# Flask应用工厂模式defcreate_app(config_name): app = Flask(__name__) app.config.from_object(config[config_name])# 初始化扩展 db.init_app(app) login_manager.init_app(app)# 注册蓝本from .main import main as main_blueprint app.register_blueprint(main_blueprint)from .api import api as api_blueprint app.register_blueprint(api_blueprint, url_prefix='/api')return app# 根据不同配置创建不同应用实例development_app = create_app('development')production_app = create_app('production')
SQLAlchemy作为Python最强大的ORM,也大量使用了设计模式:
from sqlalchemy import create_engine, Column, Integer, Stringfrom sqlalchemy.ext.declarative import declarative_basefrom sqlalchemy.orm import sessionmakerBase = declarative_base()classUser(Base): __tablename__ = 'users'id = Column(Integer, primary_key=True) name = Column(String(50))# 关系属性使用代理模式实现延迟加载# posts = relationship("Post", lazy='dynamic')# 创建会话(代理数据库连接)engine = create_engine('sqlite:///:memory:')Session = sessionmaker(bind=engine)session = Session() # 这个session就是数据库连接的代理# 延迟加载示例user = session.query(User).first()# 此时并没有真正查询关联的posts# print(user.posts) # 只有在访问时才会查询
每种设计模式都会引入一定程度的抽象,可能对性能有轻微影响,但通常可以忽略不计:
重要原则:在99%的应用场景中,代码的可维护性比微小的性能优化更重要。只有在性能瓶颈确实存在时,才考虑优化。
# 反例:过度设计classSimpleData:def__init__(self, value):self.value = value# 不必要的工厂模式classSimpleDataFactory: @staticmethoddefcreate(value):return SimpleData(value)# 正例:保持简单defcreate_simple_data(value):return {'value': value} # 甚至可以用字典
# 不好的命名classA:defm1(self, x):pass# 好的命名classOrderProcessor:defcalculate_discount(self, order_amount: float) -> float:pass
# 策略模式的测试示例import unittestdeftest_payment_strategies():"""测试不同支付策略"""# 测试支付宝 alipay = AlipayStrategy()assert alipay.pay(100) == "支付宝支付成功:100元"# 测试微信支付 wechat = WechatPayStrategy()assert wechat.pay(200) == "微信支付成功:200元"# 测试上下文切换 context = PaymentContext(alipay)assert context.execute_payment(100) == "支付宝支付成功:100元" context.set_strategy(wechat)assert context.execute_payment(200) == "微信支付成功:200元"
# 使用内置装饰器from functools import lru_cache@lru_cache(maxsize=128)defexpensive_calculation(n):"""昂贵的计算,结果会被缓存"""print(f"计算 {n}...")return n * n# 第一次计算print(expensive_calculation(10)) # 计算 10... 输出 100# 第二次从缓存获取print(expensive_calculation(10)) # 直接输出 100,不打印"计算..."
from dataclasses import dataclassfrom typing importList@dataclassclassOrder:"""使用数据类替代手动编写的__init__和__repr__""" order_id: str items: List[str] total_amount: float status: str = 'created'# 默认值# 自动生成的方法order = Order("ORD001", ["Book"], 50.0)print(order) # Order(order_id='ORD001', items=['Book'], total_amount=50.0, status='created')
- 1. 设计模式的核心思想:不是银弹,而是经过验证的最佳实践
- 2. 6种常用模式:MVC、Repository、工厂、观察者、策略、装饰器
- 3. Pythonic实现:利用Python特性写出更简洁的代码
- 2. 模式滥用:每个类都变成单例,每个函数都加装饰器
- 3. 忽视语言特性:在Python中硬套Java的设计
- 1. 阅读经典:《设计模式:可复用面向对象软件的基础》(GoF)
- 2. Python进阶:《流畅的Python》第10章"设计模式"
- 4. 框架源码:阅读Django、Flask、SQLAlchemy的源码
设计模式不是要你死记硬背的规则,而是一种思维方式。就像学烹饪,你不需要记住每道菜的精确配方,而是要理解背后的原理——什么时候用大火,什么时候用小火,各种调料如何搭配。
刚开始用模式时可能会觉得有点刻意,甚至会让简单问题变复杂。这很正常!随着经验积累,你会逐渐找到平衡点,知道什么时候该用模式,什么时候该保持简单。
记住咱们Python学习搭子的核心精神:写人类能读懂的代码。设计模式是工具,不是目的。用得好,能让你的代码更清晰;用不好,反而增加复杂度。
咱们下次见,到时候咱们一起探索更高级的主题!如果在实践中遇到问题,随时回来看看这篇文章,或者动手写个小例子试试。