Python设计模式实战

一、什么是设计模式

设计模式是软件设计中常见问题的可复用解决方案。它们是经过验证的最佳实践,可以提高代码的可维护性、可扩展性和可读性。

1.1 设计模式的分类

- 创建型模式:对象的创建
- 结构型模式:对象的组合
- 行为型模式:对象间的通信

二、单例模式(Singleton)

确保一个类只有一个实例,并提供全局访问点。

2.1 使用装饰器实现

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.2 使用元类实现

class SingletonMeta(type):
_instances = {}

def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super().__call__(*args, **kwargs)
return cls._instances[cls]

class Database(metaclass=SingletonMeta):
def __init__(self):
print("初始化数据库连接")

2.3 使用模块实现

Python的模块天然是单例的,最简单的方式:

# database.py
class Database:
def __init__(self):
print("初始化数据库连接")

db = Database()

# 使用
from database import db

三、工厂模式(Factory)

定义创建对象的接口,让子类决定实例化哪个类。

3.1 简单工厂

class Dog:
def speak(self):
return "Woof!"

class Cat:
def speak(self):
return "Meow!"

class AnimalFactory:
@staticmethod
def create_animal(animal_type):
if animal_type == "dog":
return Dog()
elif animal_type == "cat":
return Cat()
else:
raise ValueError(f"Unknown animal type: {animal_type}")

# 使用
animal = AnimalFactory.create_animal("dog")
print(animal.speak())

3.2 工厂方法

from abc import ABC, abstractmethod

class Animal(ABC):
@abstractmethod
def speak(self):
pass

class Dog(Animal):
def speak(self):
return "Woof!"

class Cat(Animal):
def speak(self):
return "Meow!"

class AnimalFactory(ABC):
@abstractmethod
def create_animal(self):
pass

def get_animal(self):
animal = self.create_animal()
return animal

class DogFactory(AnimalFactory):
def create_animal(self):
return Dog()

class CatFactory(AnimalFactory):
def create_animal(self):
return Cat()

# 使用
factory = DogFactory()
animal = factory.get_animal()
print(animal.speak())

四、建造者模式(Builder)

将复杂对象的构建与表示分离。

class Pizza:
def __init__(self):
self.size = None
self.cheese = False
self.pepperoni = False
self.mushrooms = False

def __str__(self):
return f"Pizza(size={self.size}, cheese={self.cheese}, pepperoni={self.pepperoni}, mushrooms={self.mushrooms})"

class PizzaBuilder:
def __init__(self):
self.pizza = Pizza()

def set_size(self, size):
self.pizza.size = size
return self

def add_cheese(self):
self.pizza.cheese = True
return self

def add_pepperoni(self):
self.pizza.pepperoni = True
return self

def add_mushrooms(self):
self.pizza.mushrooms = True
return self

def build(self):
return self.pizza

# 使用
pizza = (PizzaBuilder()
.set_size("large")
.add_cheese()
.add_pepperoni()
.build())

print(pizza)

五、观察者模式(Observer)

定义对象间的一对多依赖关系,当一个对象状态改变时,所有依赖者都会收到通知。

class Subject:
def __init__(self):
self._observers = []

def attach(self, observer):
if observer not in self._observers:
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 __init__(self, name):
self.name = name

def update(self, message):
print(f"{self.name} 收到消息: {message}")

# 使用
subject = Subject()

observer1 = Observer("观察者1")
observer2 = Observer("观察者2")

subject.attach(observer1)
subject.attach(observer2)

subject.notify("Hello, World!")

六、策略模式(Strategy)

定义一系列算法,将每个算法封装起来,使它们可以互换。

from abc import ABC, abstractmethod

class PaymentStrategy(ABC):
@abstractmethod
def pay(self, amount):
pass

class CreditCardPayment(PaymentStrategy):
def __init__(self, card_number):
self.card_number = card_number

def pay(self, amount):
print(f"使用信用卡 {self.card_number} 支付 {amount} 元")

class PayPalPayment(PaymentStrategy):
def __init__(self, email):
self.email = email

def pay(self, amount):
print(f"使用PayPal账户 {self.email} 支付 {amount} 元")

class ShoppingCart:
def __init__(self):
self.items = []
self.payment_strategy = None

def add_item(self, item):
self.items.append(item)

def set_payment_strategy(self, strategy):
self.payment_strategy = strategy

def checkout(self):
total = sum(item['price'] for item in self.items)
self.payment_strategy.pay(total)

# 使用
cart = ShoppingCart()
cart.add_item({'name': 'Book', 'price': 50})
cart.add_item({'name': 'Pen', 'price': 10})

cart.set_payment_strategy(CreditCardPayment("1234-5678-9012-3456"))
cart.checkout()

七、装饰器模式(Decorator)

动态地给对象添加额外的职责。

from abc import ABC, abstractmethod

class Coffee(ABC):
@abstractmethod
def cost(self):
pass

@abstractmethod
def description(self):
pass

class SimpleCoffee(Coffee):
def cost(self):
return 10

def description(self):
return "简单咖啡"

class CoffeeDecorator(Coffee):
def __init__(self, coffee):
self._coffee = coffee

def cost(self):
return self._coffee.cost()

def description(self):
return self._coffee.description()

class Milk(CoffeeDecorator):
def cost(self):
return self._coffee.cost() + 2

def description(self):
return self._coffee.description() + ", 加牛奶"

class Sugar(CoffeeDecorator):
def cost(self):
return self._coffee.cost() + 1

def description(self):
return self._coffee.description() + ", 加糖"

# 使用
coffee = SimpleCoffee()
print(f"{coffee.description()}: {coffee.cost()}元")

coffee = Milk(coffee)
print(f"{coffee.description()}: {coffee.cost()}元")

coffee = Sugar(coffee)
print(f"{coffee.description()}: {coffee.cost()}元")

八、适配器模式(Adapter)

将一个类的接口转换成客户期望的另一个接口。

class EuropeanSocket:
def voltage(self):
return 230

class USASocket:
def voltage(self):
return 120

class SocketAdapter:
def __init__(self, socket):
self.socket = socket

def voltage(self):
return self.socket.voltage()

class Laptop:
def __init__(self, socket):
self.socket = socket

def charge(self):
voltage = self.socket.voltage()
print(f"使用 {voltage}V 充电")

# 使用
eu_socket = EuropeanSocket()
adapter = SocketAdapter(eu_socket)
laptop = Laptop(adapter)
laptop.charge()

九、命令模式(Command)

将请求封装为对象,从而可以参数化客户端。

from abc import ABC, abstractmethod

class Command(ABC):
@abstractmethod
def execute(self):
pass

@abstractmethod
def undo(self):
pass

class Light:
def on(self):
print("灯打开")

def off(self):
print("灯关闭")

class LightOnCommand(Command):
def __init__(self, light):
self.light = light

def execute(self):
self.light.on()

def undo(self):
self.light.off()

class LightOffCommand(Command):
def __init__(self, light):
self.light = light

def execute(self):
self.light.off()

def undo(self):
self.light.on()

class RemoteControl:
def __init__(self):
self.command = None
self.history = []

def set_command(self, command):
self.command = command

def press_button(self):
self.command.execute()
self.history.append(self.command)

def press_undo(self):
if self.history:
command = self.history.pop()
command.undo()

# 使用
light = Light()
remote = RemoteControl()

remote.set_command(LightOnCommand(light))
remote.press_button()

remote.set_command(LightOffCommand(light))
remote.press_button()

remote.press_undo()

十、模板方法模式(Template Method)

定义算法的骨架,将某些步骤延迟到子类。

from abc import ABC, abstractmethod

class DataProcessor(ABC):
def process(self):
"""模板方法"""
self.read_data()
self.process_data()
self.save_data()

@abstractmethod
def read_data(self):
pass

@abstractmethod
def process_data(self):
pass

@abstractmethod
def save_data(self):
pass

class CSVProcessor(DataProcessor):
def read_data(self):
print("读取CSV文件")

def process_data(self):
print("处理CSV数据")

def save_data(self):
print("保存CSV结果")

class JSONProcessor(DataProcessor):
def read_data(self):
print("读取JSON文件")

def process_data(self):
print("处理JSON数据")

def save_data(self):
print("保存JSON结果")

# 使用
csv_processor = CSVProcessor()
csv_processor.process()

十一、依赖注入模式

通过外部注入依赖,而不是在类内部创建。

# 不使用依赖注入
class EmailService:
def send(self, message):
print(f"发送邮件: {message}")

class UserService:
def __init__(self):
self.email_service = EmailService() # 硬编码依赖

def register(self, user):
print(f"注册用户: {user}")
self.email_service.send(f"欢迎 {user}")

# 使用依赖注入
class UserService:
def __init__(self, email_service):
self.email_service = email_service # 注入依赖

def register(self, user):
print(f"注册用户: {user}")
self.email_service.send(f"欢迎 {user}")

# 使用
email_service = EmailService()
user_service = UserService(email_service)
user_service.register("Alice")

十二、责任链模式(Chain of Responsibility)

将请求沿着处理者链传递,直到有对象处理它。

from abc import ABC, abstractmethod

class Handler(ABC):
def __init__(self):
self.next_handler = None

def set_next(self, handler):
self.next_handler = handler
return handler

@abstractmethod
def handle(self, request):
pass

class AuthHandler(Handler):
def handle(self, request):
if not request.get('authenticated'):
print("认证失败")
return False
print("认证通过")
if self.next_handler:
return self.next_handler.handle(request)
return True

class ValidationHandler(Handler):
def handle(self, request):
if not request.get('valid'):
print("验证失败")
return False
print("验证通过")
if self.next_handler:
return self.next_handler.handle(request)
return True

class ProcessHandler(Handler):
def handle(self, request):
print("处理请求")
return True

# 使用
auth = AuthHandler()
validation = ValidationHandler()
process = ProcessHandler()

auth.set_next(validation).set_next(process)

request = {'authenticated': True, 'valid': True}
auth.handle(request)

十三、设计模式的选择

何时使用哪种模式:

1. 单例模式:全局唯一的资源(数据库连接、配置)
2. 工厂模式:对象创建逻辑复杂
3. 建造者模式:构建复杂对象
4. 观察者模式:事件驱动系统
5. 策略模式:多种算法可选
6. 装饰器模式:动态添加功能
7. 适配器模式:接口不兼容
8. 命令模式:需要撤销/重做
9. 模板方法:算法骨架固定
10. 责任链模式:多个处理者

十四、设计模式的最佳实践

1. 不要过度设计
2. 优先使用组合而不是继承
3. 针对接口编程,而不是实现
4. 保持简单(KISS原则)
5. 单一职责原则
6. 开闭原则(对扩展开放,对修改关闭)
7. 依赖倒置原则

十五、总结

设计模式是解决常见问题的经验总结,但不应该为了使用模式而使用模式。理解每种模式的适用场景和权衡,在合适的时候应用合适的模式,可以显著提高代码质量。Python的动态特性使得某些模式的实现更加简洁,但核心思想是通用的。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐