【设计模式】依赖注入和工厂模式

依赖注入与工厂模式教程(Python示例)

概述

本教程将介绍两种重要的设计模式:依赖注入(Dependency Injection) 和工厂模式(Factory Pattern),并通过Python示例展示它们的实际应用。

  1. 依赖注入 (Dependency Injection)

1.1 什么是依赖注入?

依赖注入是一种设计模式,通过外部提供对象所需的依赖关系,而不是在对象内部创建它们。这提高了代码的灵活性、可测试性和可维护性。

1.2 示例:没有使用依赖注入

python 复制代码
class EmailService:
    def send_email(self, message):
        print(f"Sending email: {message}")

class UserService:
    def __init__(self):
        self.email_service = EmailService()  # 直接创建依赖
    
    def register_user(self, username):
        # 用户注册逻辑
        self.email_service.send_email(f"Welcome {username}!")

# 使用
user_service = UserService()
user_service.register_user("Alice")

1.3 示例:使用依赖注入

python 复制代码
class EmailService:
    def send_email(self, message):
        print(f"Sending email: {message}")

class SMSService:
    def send_sms(self, message):
        print(f"Sending SMS: {message}")

class UserService:
    def __init__(self, notification_service):  # 依赖通过参数注入
        self.notification_service = notification_service
    
    def register_user(self, username):
        # 用户注册逻辑
        self.notification_service.send(f"Welcome {username}!")

# 使用依赖注入
email_service = EmailService()
user_service = UserService(email_service)
user_service.register_user("Alice")

# 可以轻松替换实现
sms_service = SMSService()
user_service_sms = UserService(sms_service)
user_service_sms.register_user("Bob")
  1. 工厂模式 (Factory Pattern)

2.1 什么是工厂模式?

工厂模式是一种创建型设计模式,它提供了一种创建对象的接口,但允许子类决定实例化哪个类。工厂方法让类的实例化推迟到子类。

2.2 简单工厂模式

python 复制代码
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}")

# 使用工厂
factory = AnimalFactory()
dog = factory.create_animal("dog")
print(dog.speak())  # 输出: Woof!

cat = factory.create_animal("cat")
print(cat.speak())  # 输出: Meow!

2.3 工厂方法模式

python 复制代码
from abc import ABC, abstractmethod

# 抽象产品
class Button(ABC):
    @abstractmethod
    def render(self):
        pass

# 具体产品
class WindowsButton(Button):
    def render(self):
        return "渲染一个Windows风格的按钮"

class WebButton(Button):
    def render(self):
        return "渲染一个Web风格的按钮"

# 抽象创建者
class Dialog(ABC):
    @abstractmethod
    def create_button(self) -> Button:
        pass
    
    def render(self):
        button = self.create_button()
        return button.render()

# 具体创建者
class WindowsDialog(Dialog):
    def create_button(self) -> Button:
        return WindowsButton()

class WebDialog(Dialog):
    def create_button(self) -> Button:
        return WebButton()

# 使用
dialog = WindowsDialog()
print(dialog.render())  # 输出: 渲染一个Windows风格的按钮

dialog = WebDialog()
print(dialog.render())  # 输出: 渲染一个Web风格的按钮
  1. 结合依赖注入和工厂模式

3.1 示例:数据库连接工厂与依赖注入

python 复制代码
from abc import ABC, abstractmethod

# 数据库连接接口
class DatabaseConnection(ABC):
    @abstractmethod
    def connect(self):
        pass
    
    @abstractmethod
    def execute_query(self, query):
        pass

# 具体实现
class MySQLConnection(DatabaseConnection):
    def connect(self):
        return "连接到MySQL数据库"
    
    def execute_query(self, query):
        return f"在MySQL上执行: {query}"

class PostgreSQLConnection(DatabaseConnection):
    def connect(self):
        return "连接到PostgreSQL数据库"
    
    def execute_query(self, query):
        return f"在PostgreSQL上执行: {query}"

# 连接工厂
class DatabaseConnectionFactory:
    @staticmethod
    def create_connection(db_type):
        if db_type == "mysql":
            return MySQLConnection()
        elif db_type == "postgresql":
            return PostgreSQLConnection()
        else:
            raise ValueError(f"不支持的数据库类型: {db_type}")

# 使用依赖注入的服务
class UserService:
    def __init__(self, db_connection: DatabaseConnection):
        self.db_connection = db_connection
        self.db_connection.connect()
    
    def get_user(self, user_id):
        query = f"SELECT * FROM users WHERE id = {user_id}"
        return self.db_connection.execute_query(query)

# 配置和应用
def main():
    # 通过工厂创建依赖
    db_factory = DatabaseConnectionFactory()
    db_connection = db_factory.create_connection("mysql")
    
    # 注入依赖
    user_service = UserService(db_connection)
    result = user_service.get_user(123)
    print(result)

if __name__ == "__main__":
    main()

3.2 更高级的依赖注入容器

python 复制代码
class DIContainer:
    def __init__(self):
        self._services = {}
        self._factories = {}
    
    def register_service(self, name, service):
        self._services[name] = service
    
    def register_factory(self, name, factory):
        self._factories[name] = factory
    
    def get_service(self, name):
        if name in self._services:
            return self._services[name]
        elif name in self._factories:
            return self._factories[name]()
        else:
            raise ValueError(f"未找到服务或工厂: {name}")

# 使用容器
container = DIContainer()
container.register_factory("db_connection", lambda: DatabaseConnectionFactory().create_connection("mysql"))
container.register_service("user_service", UserService(container.get_service("db_connection")))

# 获取服务
user_service = container.get_service("user_service")
result = user_service.get_user(123)
print(result)
  1. 总结

· 依赖注入通过外部提供依赖,提高了代码的灵活性和可测试性

· 工厂模式将对象创建逻辑封装起来,使代码更易于维护和扩展

· 结合使用这两种模式可以创建高度可配置和可测试的应用程序

这两种模式是现代软件开发中的重要概念,特别是在构建大型、可维护的应用程序时。

相关推荐
m0_743106464 小时前
NeRF+3DGS——提升渲染质量与压缩模型参数
论文阅读·人工智能·计算机视觉·3d·几何学
红苕稀饭6661 天前
Koala论文阅读
论文阅读
CV-杨帆1 天前
论文阅读:硕士学位论文 2025 面向大语言模型的黑盒对抗性攻击与防御关键技术研究
论文阅读·人工智能·语言模型
berling001 天前
【论文阅读 | WACV 2025 | MCOR:通过跨模态信息互补和余弦相似性通道重采样模块增强的多光谱目标检测】
论文阅读·人工智能·目标检测
Purple Coder1 天前
论文阅读-9月27日(入门1)
论文阅读
CV-杨帆1 天前
论文阅读:NeurIPS 2024 LLM Evaluators Recognize and Favor Their Own Generations
论文阅读
红苕稀饭6661 天前
AKS论文阅读
论文阅读
菜鸟‍1 天前
【论文笔记】基于深度学习的图像分割研究综述 和 基于深度学习的二分图像分割综述
论文阅读·人工智能·深度学习
张较瘦_1 天前
[论文阅读] 人工智能 + 软件工程 | 当传统调试遇上LLM:CodeHinter为新手程序员打造专属辅助工具
论文阅读·人工智能
berling002 天前
【论文阅读 | TGRS 2025 | DHANet:用于多模态无人机目标检测的双流分层交互网络】
论文阅读·目标检测·无人机