← 返回首页
🏗️

设计模式入门

📂 python ⏱ 3 min 406 words

设计模式入门

设计模式是解决软件设计中常见问题的可重用解决方案。Python作为一种动态语言,实现设计模式时有其独特的优雅之处。本文将介绍三种最常用的设计模式:单例、工厂和观察者模式。

单例模式

单例模式确保一个类只有一个实例,并提供全局访问点。在Python中,有多种实现方式:

使用__new__方法

class Singleton:
    _instance = None
    
    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
            cls._instance._initialized = False
        return cls._instance
    
    def __init__(self):
        if not self._initialized:
            self.data = "初始化数据"
            self._initialized = True

# 测试单例
s1 = Singleton()
s2 = Singleton()
print(s1 is s2)  # True,同一个实例

s1.data = "修改后的数据"
print(s2.data)   # "修改后的数据",共享状态

使用装饰器

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):
        self.connection = "已连接"
        print("数据库初始化完成")

# 无论创建多少次,都是同一个实例
db1 = Database()
db2 = Database()
print(db1 is db2)  # True

使用模块级别

# config.py - 最简单的单例
class _Config:
    def __init__(self):
        self.debug = False
        self.database_url = "sqlite:///default.db"

config = _Config()  # 模块加载时创建,全局唯一

# 在其他模块中
# from config import config
# config.debug = True

工厂模式

工厂模式封装了对象的创建过程,将对象的创建与使用分离,提供更大的灵活性。

简单工厂

from abc import ABC, abstractmethod

class Shape(ABC):
    """图形抽象基类"""
    @abstractmethod
    def draw(self):
        pass
    
    @abstractmethod
    def area(self):
        pass

class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius
    
    def draw(self):
        return f"绘制圆形,半径={self.radius}"
    
    def area(self):
        return 3.14 * self.radius ** 2

class Rectangle(Shape):
    def __init__(self, width, height):
        self.width = width
        self.height = height
    
    def draw(self):
        return f"绘制矩形,宽={self.width},高={self.height}"
    
    def area(self):
        return self.width * self.height

class Triangle(Shape):
    def __init__(self, base, height):
        self.base = base
        self.height = height
    
    def draw(self):
        return f"绘制三角形,底={self.base},高={self.height}"
    
    def area(self):
        return 0.5 * self.base * self.height

class ShapeFactory:
    """图形工厂"""
    _creators = {}
    
    @classmethod
    def register(cls, shape_type, creator):
        cls._creators[shape_type] = creator
    
    @classmethod
    def create(cls, shape_type, **kwargs):
        if shape_type not in cls._creators:
            raise ValueError(f"未知的图形类型: {shape_type}")
        return cls._creators[shape_type](**kwargs)

# 注册创建器
ShapeFactory.register("circle", Circle)
ShapeFactory.register("rectangle", Rectangle)
ShapeFactory.register("triangle", Triangle)

# 使用工厂
circle = ShapeFactory.create("circle", radius=5)
print(circle.draw())  # 绘制圆形,半径=5
print(f"面积: {circle.area()}")  # 面积: 78.5

观察者模式

观察者模式定义了对象间的一对多依赖关系,当一个对象状态改变时,所有依赖它的对象都会自动收到通知并更新。

from typing import List, Dict, Any
import time

class EventEmitter:
    """事件发射器,实现观察者模式"""
    
    def __init__(self):
        self._listeners: Dict[str, List[callable]] = {}
    
    def on(self, event: str, callback: callable):
        """注册事件监听器"""
        if event not in self._listeners:
            self._listeners[event] = []
        self._listeners[event].append(callback)
        return self  # 支持链式调用
    
    def emit(self, event: str, *args, **kwargs):
        """触发事件"""
        if event in self._listeners:
            for callback in self._listeners[event]:
                callback(*args, **kwargs)
    
    def remove_listener(self, event: str, callback: callable):
        """移除监听器"""
        if event in self._listeners:
            self._listeners[event] = [
                cb for cb in self._listeners[event] if cb != callback
            ]

class OrderSystem:
    """订单系统,使用观察者模式"""
    
    def __init__(self):
        self.events = EventEmitter()
    
    def create_order(self, order_id: str, amount: float):
        """创建订单"""
        print(f"创建订单: {order_id}")
        # 触发订单创建事件
        self.events.emit("order_created", order_id=order_id, amount=amount)
    
    def cancel_order(self, order_id: str):
        """取消订单"""
        print(f"取消订单: {order_id}")
        self.events.emit("order_cancelled", order_id=order_id)

# 订阅者:库存管理
def update_inventory(order_id: str, amount: float):
    print(f"[库存] 更新库存,订单: {order_id}")

# 订阅者:发送通知
def send_notification(order_id: str, amount: float):
    print(f"[通知] 发送订单确认邮件,订单: {order_id}")

# 订阅者:记录日志
def log_order(order_id: str, amount: float):
    print(f"[日志] 记录订单: {order_id}, 金额: {amount}")

# 创建订单系统并订阅事件
order_system = OrderSystem()
order_system.events.on("order_created", update_inventory)
order_system.events.on("order_created", send_notification)
order_system.events.on("order_created", log_order)

# 创建订单,所有订阅者都会收到通知
order_system.create_order("ORD001", 99.99)

选择合适的模式

设计模式不是银弹,选择时需要考虑:

在Python中,由于其动态特性,很多模式的实现比静态语言更简洁。理解设计模式的核心思想,比死记硬背实现代码更重要。