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

依赖注入与工厂模式教程(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. 总结

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

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

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

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

相关推荐
Rocky Ding*8 小时前
一文读懂Wan 3.0视频创作大模型核心基础知识
论文阅读·人工智能·深度学习·机器学习·aigc·ai-native·wan 3.0
sel_913 小时前
【多轮对话论文导读(七)】多轮对话论文阅读笔记:从数据生成、用户模拟到上下文重构与长期记忆
论文阅读·人工智能·笔记·深度学习·算法·语言模型·自然语言处理
柳叶方舟14 小时前
Nature Aging IF=19.4 | Transformer聚类框架:纵向电子健康记录解析阿尔茨海默病与帕金森病亚型
论文阅读·人工智能·深度学习·transformer·健康医疗·聚类
西柚小萌新1 天前
【论文阅读】-- 面向多模态检索增强生成(MRAG)的知识投毒攻击
论文阅读
Rocky Ding*1 天前
【三年面试五年模拟】2026-08-18_哔哩哔哩_AI应用岗Agent开发一面面经(含完整答案)
论文阅读·人工智能·深度学习·机器学习·aigc·ai-native·ai agent
m4Rk_1 天前
【论文阅读】Agent 记忆机制(50):PACE——按下一步预测价值动态分配历史记忆粒度
论文阅读·人工智能·学习·开源·github
传说故事2 天前
【多篇论文阅读】Interactive World Models
论文阅读·人工智能·生成模型
传说故事3 天前
【论文阅读】Whole-Body Conditioned Egocentric Video Prediction
论文阅读·人工智能·生成模型
chnyi6_ya3 天前
论文阅读笔记 | From Priors to Perception: Grounding Video-LLMs in Physical Reality
论文阅读·笔记
m4Rk_3 天前
【论文阅读】Agent 记忆机制(49):MemCoE——先学习如何组织记忆,再学习具体记住什么
论文阅读·人工智能·学习·开源·github