学无止境

少年辛苦终身事,莫向光阴惰寸功。——唐·杜荀鹤《题弟侄书堂》


Python设计模式详解

设计模式


  • 设计模式是高成次的方案,并不关心具体的实现细节
  • 比如算法和数据结构和网页。对应正在尝试解决问题,何种算法和数据结构最优,则是由软件工程师自己把握。

1. 设计模式概述

1.1 什么是设计模式

设计模式是软件开发过程中的最佳实践方案,它是经过多年验证的、可重用的解决方案。设计模式主要关注:

  • 代码的可重用性
  • 可维护性
  • 可读性
  • 稳健的面向对象设计

1.2 设计模式的重要性

  • 提供标准化的解决方案
  • 便于团队沟通
  • 提高代码质量
  • 降低维护成本

2. 工厂模式

2.1 简单工厂模式

2.1.1 基本概念

简单工厂模式通过一个工厂类统一管理对象的创建过程。

# 产品基类
class Vehicle:
    def drive(self):
        pass

# 具体产品
class Car(Vehicle):
    def drive(self):
        return "Car is driving"

class Truck(Vehicle):
    def drive(self):
        return "Truck is driving"

# 简单工厂
class VehicleFactory:
    @staticmethod
    def create_vehicle(vehicle_type):
        if vehicle_type == "car":
            return Car()
        elif vehicle_type == "truck":
            return Truck()
        raise ValueError(f"Unknown vehicle type: {vehicle_type}")

# 使用示例
factory = VehicleFactory()
car = factory.create_vehicle("car")
print(car.drive())  # 输出: Car is driving

2.1.2 优缺点

优点:

  • 封装对象创建过程
  • 客户端与具体实现解耦

缺点:

  • 违反开闭原则,添加新产品需要修改工厂类
  • 工厂类职责过重

2.2 工厂方法模式

2.2.1 基本概念

工厂方法模式为每个产品提供一个专门的工厂类。

# 抽象工厂接口
class VehicleFactory:
    def create_vehicle(self):
        pass

# 具体工厂
class CarFactory(VehicleFactory):
    def create_vehicle(self):
        return Car()

class TruckFactory(VehicleFactory):
    def create_vehicle(self):
        return Truck()

# 使用示例
car_factory = CarFactory()
car = car_factory.create_vehicle()
print(car.drive())

2.2.2 优缺点

优点:

  • 符合开闭原则
  • 更好的扩展性
  • 解耦性更强

缺点:

  • 类的数量增多
  • 系统复杂度增加

3. __new__方法详解

3.1 基本概念

__new__是Python中创建对象的特殊方法,它在__init__之前被调用。

class CustomClass:
    def __new__(cls, *args, **kwargs):
        print("1. 调用__new__方法")
        instance = super().__new__(cls)
        return instance

    def __init__(self, value):
        print("2. 调用__init__方法")
        self.value = value

# 创建实例
obj = CustomClass(42)

3.2 __new__方法的特点

  1. 必须有cls参数
  2. 必须返回一个实例
  3. 在对象创建过程中最先被调用

3.3 实际应用场景

3.3.1 单例模式实现

class Singleton:
    _instance = None
    
    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance
    
    def __init__(self):
        # 初始化代码
        pass

3.3.2 不可变类型

class Immutable:
    def __new__(cls, value):
        instance = super().__new__(cls)
        instance._value = value
        return instance
    
    @property
    def value(self):
        return self._value

4. 单例模式

4.1 实现方式

4.1.1 使用__new__方法

class Singleton:
    _instance = None
    
    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance

# 测试
s1 = Singleton()
s2 = Singleton()
print(s1 is s2)  # True

4.1.2 使用装饰器

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.connected = False
    
    def connect(self):
        if not self.connected:
            # 模拟数据库连接
            self.connected = True
            return "Database connected"

4.2 单例模式的应用场景

  1. 数据库连接池
  2. 配置管理器
  3. 日志管理器
  4. 缓存管理
# 配置管理器示例
class ConfigManager:
    _instance = None
    _config = {}
    
    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance
    
    def load_config(self, filename):
        # 模拟加载配置文件
        self._config = {
            'database': 'mysql://localhost:3306',
            'debug': True
        }
    
    def get_config(self, key):
        return self._config.get(key)

# 使用示例
config = ConfigManager()
config.load_config('config.ini')
print(config.get_config('database'))

4.3 最佳实践建议

  1. 注意线程安全
import threading

class ThreadSafeSingleton:
    _instance = None
    _lock = threading.Lock()
    
    def __new__(cls):
        if cls._instance is None:
            with cls._lock:
                if cls._instance is None:
                    cls._instance = super().__new__(cls)
        return cls._instance
  1. 考虑序列化问题
import pickle

class SingletonWithPickle:
    _instance = None
    
    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance
    
    def __reduce__(self):
        return self.__class__, ()