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
抽象方法;Circle
和Square
类实现了Shape
接口,具体画啥样子它们说了算;ShapeFactory
是一个抽象基类,定义了create_shape
抽象方法;CircleFactory
和SquareFactory
类实现了ShapeFactory
接口,分别负责创建Circle
和Square
对象;- 我们只需通过调用具体的工厂类(如
CircleFactory
或SquareFactory
)来创建形状对象,然后调用相应的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
抽象方法;InfoLogger
和ErrorLogger
类实现了Logger
接口,分别负责记录不同级别的日志;LoggerFactory
是一个抽象基类,定义了create_logger
抽象方法;InfoLoggerFactory
和ErrorLoggerFactory
类实现了LoggerFactory
接口,分别负责创建InfoLogger
和ErrorLogger
对象;- 你只需通过调用具体的工厂类(如
InfoLoggerFactory
或ErrorLoggerFactory
)来创建日志记录器对象,然后调用相应的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
抽象方法;MySQLConnection
和PostgreSQLConnection
类实现了DatabaseConnection
接口,分别负责不同数据库的连接;DatabaseConnectionFactory
是一个抽象基类,定义了create_connection
抽象方法;MySQLConnectionFactory
和PostgreSQLConnectionFactory
类实现了DatabaseConnectionFactory
接口,分别负责创建MySQLConnection
和PostgreSQLConnection
对象;- 你只需通过调用具体的工厂类(如
MySQLConnectionFactory
或PostgreSQLConnectionFactory
)来创建数据库连接对象,然后调用相应的connect
方法。
4. 工厂方法模式的优缺点
优点
- 解耦:将对象的创建过程与使用过程分离,降低了代码的耦合度;
- 灵活性:通过子类来决定具体实例化哪个类,增加了代码的灵活性;
- 扩展性:增加新的产品类时,只需添加相应的工厂类即可,不需要修改现有代码。
缺点
- 类的数量增加:每增加一个产品类,都需要增加一个相应的工厂类,导致类的数量增多;
- 代码复杂度提高:增加了系统的复杂性,理解起来可能会有些困难。
5. 图示
类图
示意图
6. 总结
工厂方法模式是一个非常有用的设计模式,通过定义一个创建对象的接口,让子类来决定实例化哪一个类,增加了代码的灵活性和可扩展性。虽然它会增加类的数量和代码的复杂度,但在大多数情况下,工厂方法模式依然是一个非常实用的解决方案。希望今天的分享能让大家对工厂方法模式有更深入的理解,如果你在项目中也用到了工厂方法模式,欢迎留言分享你的经验和见解!