灵活多变的对象创建——工厂方法模式(Python实现)

1. 引言

大家好,又见面了!在上一篇文章中,我们聊了聊简单工厂模式,今天,我们要进一步探讨一种更加灵活的工厂设计模式——工厂方法模式。如果说简单工厂模式是“万能钥匙”,那工厂方法模式就是“变形金刚”。它通过定义一个创建对象的接口,让子类决定实例化哪一个类,从而应对各种变化。今天,我们就来揭开工厂方法模式的神秘面纱,让你的Python代码更加灵活多变。准备好了吗?Let’s go!

2. 什么是工厂方法模式

工厂方法模式(Factory Method Pattern)是一种创建型设计模式,它定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法模式使一个类的实例化延迟到其子类,简而言之,就是父类提供一个接口,子类来决定实例化哪个具体的类。

3. 工厂方法模式的实现(Python)

示例一:形状工厂

假如你是个艺术家,需要画各种形状,圆形、方形啥的,你可以用工厂方法模式让子类决定创建哪些形状对象:

代码实现
from abc import ABC, abstractmethod

# 定义Shape接口
class Shape(ABC):
    @abstractmethod
    def draw(self):
        pass

# 实现Circle类
class Circle(Shape):
    def draw(self):
        print("Drawing a Circle")

# 实现Square类
class Square(Shape):
    def draw(self):
        print("Drawing a Square")

# 定义ShapeFactory接口
class ShapeFactory(ABC):
    @abstractmethod
    def create_shape(self):
        pass

# 实现CircleFactory类
class CircleFactory(ShapeFactory):
    def create_shape(self):
        return Circle()

# 实现SquareFactory类
class SquareFactory(ShapeFactory):
    def create_shape(self):
        return Square()

# 使用示例
if __name__ == "__main__":
    circle_factory = CircleFactory()
    shape1 = circle_factory.create_shape()
    shape1.draw()  # 输出: Drawing a Circle

    square_factory = SquareFactory()
    shape2 = square_factory.create_shape()
    shape2.draw()  # 输出: Drawing a Square
详细代码解析
  • Shape是一个抽象基类,定义了draw抽象方法;
  • CircleSquare类实现了Shape接口,具体画啥样子它们说了算;
  • ShapeFactory是一个抽象基类,定义了create_shape抽象方法;
  • CircleFactorySquareFactory类实现了ShapeFactory接口,分别负责创建CircleSquare对象;
  • 我们只需通过调用具体的工厂类(如CircleFactorySquareFactory)来创建形状对象,然后调用相应的draw方法。
示例二:日志记录器工厂

现在你是个开发者,搞个日志系统,你想要不同级别的日志记录器来帮你分门别类记录信息,工厂方法模式也能派上用场:

码实现
from abc import ABC, abstractmethod

# 定义Logger接口
class Logger(ABC):
    @abstractmethod
    def log(self, message):
        pass

# 实现InfoLogger类
class InfoLogger(Logger):
    def log(self, message):
        print(f"INFO: {message}")

# 实现ErrorLogger类
class ErrorLogger(Logger):
    def log(self, message):
        print(f"ERROR: {message}")

# 定义LoggerFactory接口
class LoggerFactory(ABC):
    @abstractmethod
    def create_logger(self):
        pass

# 实现InfoLoggerFactory类
class InfoLoggerFactory(LoggerFactory):
    def create_logger(self):
        return InfoLogger()

# 实现ErrorLoggerFactory类
class ErrorLoggerFactory(LoggerFactory):
    def create_logger(self):
        return ErrorLogger()

# 使用示例
if __name__ == "__main__":
    info_logger_factory = InfoLoggerFactory()
    info_logger = info_logger_factory.create_logger()
    info_logger.log("This is an informational message.")  # 输出: INFO: This is an informational message.

    error_logger_factory = ErrorLoggerFactory()
    error_logger = error_logger_factory.create_logger()
    error_logger.log("This is an error message.")  # 输出: ERROR: This is an error message.
详细代码解析
  • Logger是一个抽象基类,定义了log抽象方法;
  • InfoLoggerErrorLogger类实现了Logger接口,分别负责记录不同级别的日志;
  • LoggerFactory是一个抽象基类,定义了create_logger抽象方法;
  • InfoLoggerFactoryErrorLoggerFactory类实现了LoggerFactory接口,分别负责创建InfoLoggerErrorLogger对象;
  • 你只需通过调用具体的工厂类(如InfoLoggerFactoryErrorLoggerFactory)来创建日志记录器对象,然后调用相应的log方法。
示例三:数据库连接工厂

假如你现在是个DBA,需要管理多个数据库连接,工厂方法模式同样能帮你搞定这个问题:

代码实现
from abc import ABC, abstractmethod

# 定义DatabaseConnection接口
class DatabaseConnection(ABC):
    @abstractmethod
    def connect(self):
        pass

# 实现MySQLConnection类
class MySQLConnection(DatabaseConnection):
    def connect(self):
        print("Connecting to MySQL database...")

# 实现PostgreSQLConnection类
class PostgreSQLConnection(DatabaseConnection):
    def connect(self):
        print("Connecting to PostgreSQL database...")

# 定义DatabaseConnectionFactory接口
class DatabaseConnectionFactory(ABC):
    @abstractmethod
    def create_connection(self):
        pass

# 实现MySQLConnectionFactory类
class MySQLConnectionFactory(DatabaseConnectionFactory):
    def create_connection(self):
        return MySQLConnection()

# 实现PostgreSQLConnectionFactory类
class PostgreSQLConnectionFactory(DatabaseConnectionFactory):
    def create_connection(self):
        return PostgreSQLConnection()

# 使用示例
if __name__ == "__main__":
    mysql_factory = MySQLConnectionFactory()
    mysql_connection = mysql_factory.create_connection()
    mysql_connection.connect()  # 输出: Connecting to MySQL database...

    postgresql_factory = PostgreSQLConnectionFactory()
    postgresql_connection = postgresql_factory.create_connection()
    postgresql_connection.connect()  # 输出: Connecting to PostgreSQL database...
详细代码解析
  • DatabaseConnection是一个抽象基类,定义了connect抽象方法;
  • MySQLConnectionPostgreSQLConnection类实现了DatabaseConnection接口,分别负责不同数据库的连接;
  • DatabaseConnectionFactory是一个抽象基类,定义了create_connection抽象方法;
  • MySQLConnectionFactoryPostgreSQLConnectionFactory类实现了DatabaseConnectionFactory接口,分别负责创建MySQLConnectionPostgreSQLConnection对象;
  • 你只需通过调用具体的工厂类(如MySQLConnectionFactoryPostgreSQLConnectionFactory)来创建数据库连接对象,然后调用相应的connect方法。

4. 工厂方法模式的优缺点

优点
  • 解耦:将对象的创建过程与使用过程分离,降低了代码的耦合度;
  • 灵活性:通过子类来决定具体实例化哪个类,增加了代码的灵活性;
  • 扩展性:增加新的产品类时,只需添加相应的工厂类即可,不需要修改现有代码。
缺点
  • 类的数量增加:每增加一个产品类,都需要增加一个相应的工厂类,导致类的数量增多;
  • 代码复杂度提高:增加了系统的复杂性,理解起来可能会有些困难。

5. 图示

类图
../_images/FactoryMethod.jpg
示意图

img

6. 总结

工厂方法模式是一个非常有用的设计模式,通过定义一个创建对象的接口,让子类来决定实例化哪一个类,增加了代码的灵活性和可扩展性。虽然它会增加类的数量和代码的复杂度,但在大多数情况下,工厂方法模式依然是一个非常实用的解决方案。希望今天的分享能让大家对工厂方法模式有更深入的理解,如果你在项目中也用到了工厂方法模式,欢迎留言分享你的经验和见解!
在这里插入图片描述

相关推荐

  1. 工厂方法模式灵活创建对象实例

    2024-07-09 22:56:03       33 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-09 22:56:03       50 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-09 22:56:03       54 阅读
  3. 在Django里面运行非项目文件

    2024-07-09 22:56:03       43 阅读
  4. Python语言-面向对象

    2024-07-09 22:56:03       54 阅读

热门阅读

  1. Linux下网络编程-简易poll服务器和客户端

    2024-07-09 22:56:03       20 阅读
  2. ClickHouse表引擎概述

    2024-07-09 22:56:03       18 阅读
  3. svn常用命令

    2024-07-09 22:56:03       21 阅读
  4. 面向对象——继承、封装、多态

    2024-07-09 22:56:03       17 阅读
  5. CoppeliaSim的简单教程

    2024-07-09 22:56:03       21 阅读
  6. cadence许可管理策略

    2024-07-09 22:56:03       18 阅读
  7. Android动态设置系统音量最大值

    2024-07-09 22:56:03       23 阅读
  8. Android Enable 和clickable

    2024-07-09 22:56:03       18 阅读