1. 引言
大家好,又見面了!在上一篇文章中,我們聊了聊簡單工廠模式,今天,我們要進一步探討一種更加靈活的工廠設計模式——工廠方法模式。如果說簡單工廠模式是“萬能鑰匙”,那工廠方法模式就是“變形金剛”。它通過定義一個創建對象的接口,讓子類決定實例化哪一個類,從而應對各種變化。今天,我們就來揭開工廠方法模式的神秘面紗,讓你的Python代碼更加靈活多變。準備好了嗎?Let’s go!
2. 什么是工廠方法模式
工廠方法模式(Factory Method Pattern)是一種創建型設計模式,它定義了一個創建對象的接口,但由子類決定要實例化的類是哪一個。工廠方法模式使一個類的實例化延遲到其子類,簡而言之,就是父類提供一個接口,子類來決定實例化哪個具體的類。
3. 工廠方法模式的實現(Python)
示例一:形狀工廠
假如你是個藝術家,需要畫各種形狀,圓形、方形啥的,你可以用工廠方法模式讓子類決定創建哪些形狀對象:
代碼實現
from abc import ABC, abstractmethod# 定義Shape接口
class Shape(ABC):@abstractmethoddef 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):@abstractmethoddef 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 Circlesquare_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):@abstractmethoddef 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):@abstractmethoddef 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):@abstractmethoddef 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):@abstractmethoddef 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. 總結
工廠方法模式是一個非常有用的設計模式,通過定義一個創建對象的接口,讓子類來決定實例化哪一個類,增加了代碼的靈活性和可擴展性。雖然它會增加類的數量和代碼的復雜度,但在大多數情況下,工廠方法模式依然是一個非常實用的解決方案。希望今天的分享能讓大家對工廠方法模式有更深入的理解,如果你在項目中也用到了工廠方法模式,歡迎留言分享你的經驗和見解!