Python设计模式实战
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的动态特性使得某些模式的实现更加简洁,但核心思想是通用的。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐
所有评论(0)