彻底搞懂Java工厂方法模式:从入门到实战,一篇就够!
一、引言
在软件开发的世界中,设计模式就像是一套通用的解决方案,帮助开发者们应对各种常见的编程问题。今天,我们要来深入探讨创建型设计模式中的工厂方法模式。
工厂方法模式是一种非常实用的设计模式,它提供了一种创建对象的方式,将对象的创建和使用分离,使得代码更加灵活、可维护和可扩展。这种模式在许多开源框架和实际项目中都有广泛的应用,比如我们熟知的 Spring 框架、JDBC 等。
接下来,我将通过一个通俗易懂的案例,结合 Java 代码,详细介绍工厂方法模式的实现细节和应用场景,让你轻松掌握这一强大的设计模式。
二、核心概念
2.1 定义与核心思想
工厂方法模式,定义一个创建对象的接口,让子类决定实例化哪个类。简单来说,就是把对象的创建过程交给子类去实现,工厂类只负责提供一个统一的创建对象的接口。这样做的好处是,当我们需要创建不同类型的对象时,只需要创建对应的子类工厂即可,而不需要修改工厂类的代码,符合开闭原则。
其核心思想在于,通过抽象工厂类来统一管理对象的创建逻辑,将具体的创建过程延迟到子类中进行。这样可以将对象的创建和使用分离,使得代码更加灵活、可维护和可扩展。同时,也符合依赖倒置原则,即高层模块不依赖于低层模块,而是依赖于抽象。在工厂方法模式中,高层模块(客户端)只依赖于抽象工厂和抽象产品,而不依赖于具体的实现类。
2.2 四大角色
抽象产品(Product):定义了产品的公共接口,是所有具体产品的抽象父类或接口。在实际应用中,抽象产品可以是一个抽象类,也可以是一个接口,它定义了产品的基本行为和属性。例如,在一个图形绘制系统中,抽象产品可以是一个Shape
接口,定义了绘制图形的基本方法draw()
。
// 抽象产品接口
public interface Shape {
void draw();
}
具体产品(ConcreteProduct):实现了抽象产品接口的具体类,代表了具体的产品。每个具体产品都有自己独特的实现逻辑,实现了抽象产品中定义的方法。例如,在上述图形绘制系统中,Circle
和Rectangle
就是具体产品,它们分别实现了Shape
接口的draw()
方法,用于绘制圆形和矩形。
// 具体产品类Circle
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("绘制圆形");
}
}
// 具体产品类Rectangle
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("绘制矩形");
}
}
抽象工厂(Creator):声明了工厂方法的抽象类或接口,它不负责具体产品的创建,而是为具体工厂提供一个统一的接口。抽象工厂中通常包含一个抽象的工厂方法,该方法返回一个抽象产品类型的对象。例如,在图形绘制系统中,抽象工厂可以是一个ShapeFactory
接口,定义了创建图形的抽象方法createShape()
。
// 抽象工厂接口
public interface ShapeFactory {
Shape createShape();
}
具体工厂(ConcreteCreator):实现了抽象工厂接口的具体类,负责创建具体的产品对象。每个具体工厂对应一个具体产品,在其实现的工厂方法中返回具体产品的实例。例如,在图形绘制系统中,CircleFactory
和RectangleFactory
就是具体工厂,它们分别实现了ShapeFactory
接口的createShape()
方法,返回Circle
和Rectangle
的实例。
// 具体工厂类CircleFactory
public class CircleFactory implements ShapeFactory {
@Override
public Shape createShape() {
return new Circle();
}
}
// 具体工厂类RectangleFactory
public class RectangleFactory implements ShapeFactory {
@Override
public Shape createShape() {
return new Rectangle();
}
}
2.3 适用场景
对象创建过程复杂,需要统一管理:当对象的创建过程涉及到复杂的初始化操作、资源获取、依赖注入等,使用工厂方法模式可以将这些复杂的创建逻辑封装在工厂类中,使得代码更加简洁和可维护。例如,在一个数据库连接池的实现中,创建数据库连接的过程涉及到加载驱动、配置连接参数等复杂操作,使用工厂方法模式可以将这些操作封装在工厂类中,客户端只需要调用工厂方法获取数据库连接即可。
系统需要支持多类产品扩展:如果系统中需要不断添加新的产品类型,并且希望在添加新产品时尽量减少对现有代码的修改,工厂方法模式是一个很好的选择。因为在工厂方法模式中,每增加一个新产品,只需要创建一个对应的具体工厂类,而不需要修改抽象工厂和其他具体工厂的代码,符合开闭原则。例如,在一个电商系统中,随着业务的发展,可能会不断添加新的商品类型,使用工厂方法模式可以方便地扩展商品类型。
希望将产品的使用与创建解耦:工厂方法模式将产品的创建和使用分离,使得客户端只需要关注产品的使用,而不需要关心产品的创建细节。这样可以降低客户端与具体产品类之间的耦合度,提高代码的可维护性和可扩展性。例如,在一个游戏开发中,游戏角色的创建过程可能非常复杂,使用工厂方法模式可以将角色的创建过程封装在工厂类中,游戏开发者只需要使用工厂方法获取角色对象即可,而不需要关心角色是如何创建的。
三、实现步骤详解
3.1 基础实现示例
下面我们通过一个简单的图形绘制系统来详细展示工厂方法模式的实现过程。假设我们要绘制不同形状的图形,如圆形和矩形,我们可以按照以下步骤实现工厂方法模式:
定义抽象产品接口:首先,我们需要定义一个抽象产品接口,用于描述所有具体产品的公共行为。在这个例子中,我们定义一个Shape
接口,其中包含一个draw
方法,用于绘制图形。
// 抽象产品接口
public interface Shape {
void draw();
}
实现具体产品类:接着,我们实现具体的产品类,这些类实现了抽象产品接口,并且提供了具体的实现逻辑。在这个例子中,我们实现了Circle
和Rectangle
两个具体产品类,分别用于绘制圆形和矩形。
// 具体产品类Circle
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("绘制圆形");
}
}
// 具体产品类Rectangle
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("绘制矩形");
}
}
定义抽象工厂接口:然后,我们定义一个抽象工厂接口,用于声明创建产品对象的方法。在这个例子中,我们定义一个ShapeFactory
接口,其中包含一个createShape
方法,用于创建Shape
对象。
// 抽象工厂接口
public interface ShapeFactory {
Shape createShape();
}
实现具体工厂类:最后,我们实现具体的工厂类,这些类实现了抽象工厂接口,并且在其实现的工厂方法中返回具体产品的实例。在这个例子中,我们实现了CircleFactory
和RectangleFactory
两个具体工厂类,分别用于创建Circle
和Rectangle
对象。
// 具体工厂类CircleFactory
public class CircleFactory implements ShapeFactory {
@Override
public Shape createShape() {
return new Circle();
}
}
// 具体工厂类RectangleFactory
public class RectangleFactory implements ShapeFactory {
@Override
public Shape createShape() {
return new Rectangle();
}
}
客户端调用:在客户端代码中,我们可以通过具体工厂类来创建具体产品对象,并调用其方法。例如:
public class Client {
public static void main(String[] args) {
// 使用CircleFactory创建Circle对象
ShapeFactory circleFactory = new CircleFactory();
Shape circle = circleFactory.createShape();
circle.draw();
// 使用RectangleFactory创建Rectangle对象
ShapeFactory rectangleFactory = new RectangleFactory();
Shape rectangle = rectangleFactory.createShape();
rectangle.draw();
}
}
在上述代码中,客户端通过CircleFactory
和RectangleFactory
分别创建了Circle
和Rectangle
对象,并调用它们的draw
方法进行绘制。这样,我们就完成了工厂方法模式的基础实现。
3.2 结合反射的动态实现
在实际应用中,我们可能希望更加灵活地创建对象,例如根据配置文件或用户输入来动态创建对象。这时,我们可以结合反射机制来实现动态的工厂方法模式。下面是一个结合反射的动态实现示例:
定义抽象产品接口和具体产品类:这部分与基础实现示例相同,不再赘述。
修改抽象工厂接口和具体工厂类:我们可以将具体工厂类的创建逻辑封装在一个工具类中,通过反射来创建具体产品对象。首先,我们修改抽象工厂接口,添加一个根据类名创建对象的方法。
// 抽象工厂接口
public interface ShapeFactory {
Shape createShape(String className);
}
然后,我们实现一个工具类ShapeFactoryUtil
,用于通过反射创建对象。
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class ShapeFactoryUtil {
public static Shape createShape(String className) {
try {
// 根据类名获取Class对象
Class<?> clazz = Class.forName(className);
// 获取无参构造函数
Constructor<?> constructor = clazz.getConstructor();
// 通过构造函数创建对象
return (Shape) constructor.newInstance();
} catch (ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
return null;
}
}
}
客户端调用:在客户端代码中,我们可以通过ShapeFactoryUtil
来动态创建对象。例如,假设我们从配置文件中读取要创建的对象类名,然后使用ShapeFactoryUtil
来创建对象。
public class Client {
public static void main(String[] args) {
// 假设从配置文件中读取的类名
String circleClassName = "com.example.Circle";
String rectangleClassName = "com.example.Rectangle";
// 使用ShapeFactoryUtil创建Circle对象
Shape circle = ShapeFactoryUtil.createShape(circleClassName);
if (circle != null) {
circle.draw();
}
// 使用ShapeFactoryUtil创建Rectangle对象
Shape rectangle = ShapeFactoryUtil.createShape(rectangleClassName);
if (rectangle != null) {
rectangle.draw();
}
}
}
在上述代码中,客户端通过ShapeFactoryUtil
根据类名动态创建了Circle
和Rectangle
对象,并调用它们的draw
方法进行绘制。通过结合反射机制,我们实现了更加灵活的工厂方法模式,使得系统在创建对象时更加动态和可扩展。
四、优缺点分析
工厂方法模式作为一种广泛应用的设计模式,具有诸多优点,但同时也存在一些缺点,在实际应用中需要我们根据具体情况进行权衡。
4.1 优点
符合开闭原则,扩展性强:在工厂方法模式中,当我们需要添加新的产品时,只需要创建一个新的具体产品类和对应的具体工厂类,而不需要修改抽象工厂和其他已有的具体工厂类的代码。这使得系统具有良好的扩展性,能够轻松应对业务需求的变化。例如,在上述图形绘制系统中,如果我们要添加一个新的图形,如三角形,只需要创建Triangle
类实现Shape
接口,并创建TriangleFactory
类实现ShapeFactory
接口,而不需要修改其他已有的代码。
解耦产品创建与使用:工厂方法模式将产品的创建和使用分离,客户端只需要通过抽象工厂接口获取产品,而不需要关心产品的具体创建过程。这样可以降低客户端与具体产品类之间的耦合度,提高代码的可维护性和可扩展性。例如,在一个电商系统中,订单的创建过程可能涉及到多个复杂的步骤,使用工厂方法模式可以将订单的创建过程封装在工厂类中,客户端只需要调用工厂方法获取订单对象即可,而不需要关心订单是如何创建的。
支持多产品族扩展:虽然工厂方法模式主要用于创建同一等级结构的产品,但通过适当的设计,也可以支持多产品族的扩展。例如,在一个游戏开发中,可能存在不同类型的游戏角色,每个角色都有自己的属性和行为,使用工厂方法模式可以为每个角色创建一个对应的工厂类,从而方便地扩展新的角色类型。
4.2 缺点
类数量增加,复杂度提升:由于工厂方法模式为每个具体产品都提供了一个对应的具体工厂类,当产品种类较多时,会导致类的数量急剧增加,从而增加系统的复杂度和维护成本。例如,在一个大型电商系统中,可能存在成千上万种商品,为每种商品都创建一个具体工厂类显然是不现实的,这时候就需要考虑使用其他设计模式来优化。
客户端需知道具体工厂类:在工厂方法模式中,客户端需要知道具体的工厂类才能获取到所需的产品对象。这就要求客户端必须了解系统中具体工厂类的存在和使用方式,增加了客户端的使用难度和依赖。例如,在上述图形绘制系统中,客户端需要知道CircleFactory
和RectangleFactory
等具体工厂类才能创建相应的图形对象,如果系统中工厂类的名称或结构发生变化,客户端的代码也需要相应地修改。
可能过度设计简单场景:对于一些简单的场景,使用工厂方法模式可能会显得过于复杂,增加了不必要的代码量和开发成本。例如,在一个小型的 Java 项目中,如果只需要创建少量的对象,并且对象的创建过程非常简单,直接使用new
关键字创建对象可能更加简洁明了,而使用工厂方法模式反而会使代码变得繁琐。
五、高级应用场景
5.1 日志工厂案例
在大型项目中,日志记录是必不可少的功能。不同的模块可能需要使用不同类型的日志记录方式,如控制台日志、文件日志、数据库日志等。使用工厂方法模式可以很好地管理这些不同类型的日志记录器的创建。
假设我们有一个Logger
接口,用于定义日志记录的方法,然后有ConsoleLogger
、FileLogger
和DatabaseLogger
等具体的日志记录器实现类。
// 抽象日志记录器接口
public interface Logger {
void log(String message);
}
// 控制台日志记录器
public class ConsoleLogger implements Logger {
@Override
public void log(String message) {
System.out.println("[Console] " + message);
}
}
// 文件日志记录器
import java.io.FileWriter;
import java.io.IOException;
public class FileLogger implements Logger {
private String filePath;
public FileLogger(String filePath) {
this.filePath = filePath;
}
@Override
public void log(String message) {
try (FileWriter writer = new FileWriter(filePath, true)) {
writer.write(message + "\n");
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 数据库日志记录器(假设使用JDBC)
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class DatabaseLogger implements Logger {
private String url;
private String username;
private String password;
public DatabaseLogger(String url, String username, String password) {
this.url = url;
this.username = username;
this.password = password;
}
@Override
public void log(String message) {
String sql = "INSERT INTO logs (message) VALUES (?)";
try (Connection connection = DriverManager.getConnection(url, username, password);
PreparedStatement statement = connection.prepareStatement(sql)) {
statement.setString(1, message);
statement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
接下来,我们定义抽象工厂接口LoggerFactory
和具体的工厂实现类。
// 抽象日志工厂接口
public interface LoggerFactory {
Logger createLogger();
}
// 控制台日志工厂
public class ConsoleLoggerFactory implements LoggerFactory {
@Override
public Logger createLogger() {
return new ConsoleLogger();
}
}
// 文件日志工厂
public class FileLoggerFactory implements LoggerFactory {
private String filePath;
public FileLoggerFactory(String filePath) {
this.filePath = filePath;
}
@Override
public Logger createLogger() {
return new FileLogger(filePath);
}
}
// 数据库日志工厂
public class DatabaseLoggerFactory implements LoggerFactory {
private String url;
private String username;
private String password;
public DatabaseLoggerFactory(String url, String username, String password) {
this.url = url;
this.username = username;
this.password = password;
}
@Override
public Logger createLogger() {
return new DatabaseLogger(url, username, password);
}
}
在客户端代码中,我们可以根据需要选择不同的日志工厂来创建日志记录器。
public class Client {
public static void main(String[] args) {
// 使用控制台日志工厂创建日志记录器
LoggerFactory consoleFactory = new ConsoleLoggerFactory();
Logger consoleLogger = consoleFactory.createLogger();
consoleLogger.log("This is a console log message");
// 使用文件日志工厂创建日志记录器
LoggerFactory fileFactory = new FileLoggerFactory("logs.txt");
Logger fileLogger = fileFactory.createLogger();
fileLogger.log("This is a file log message");
// 使用数据库日志工厂创建日志记录器(假设数据库连接信息已配置)
LoggerFactory dbFactory = new DatabaseLoggerFactory("jdbc:mysql://localhost:3306/mydb", "root", "password");
Logger dbLogger = dbFactory.createLogger();
dbLogger.log("This is a database log message");
}
}
通过这种方式,我们将日志记录器的创建和使用分离,使得系统在添加新的日志记录方式时更加灵活,只需要创建新的具体日志记录器类和对应的工厂类即可,而不需要修改客户端代码。
5.2 数据库连接工厂
在开发数据库相关的应用时,不同的数据库类型(如 MySQL、Oracle、SQL Server 等)需要不同的连接方式和配置。使用工厂方法模式可以将数据库连接的创建过程封装起来,方便管理和扩展。
假设我们有一个DatabaseConnection
接口,用于定义数据库连接的基本操作,然后有MySQLConnection
、OracleConnection
和SQLServerConnection
等具体的数据库连接实现类。
// 抽象数据库连接接口
public interface DatabaseConnection {
void connect();
void disconnect();
}
// MySQL数据库连接
public class MySQLConnection implements DatabaseConnection {
@Override
public void connect() {
System.out.println("Connecting to MySQL database");
// 实际的连接代码,如加载驱动、建立连接等
}
@Override
public void disconnect() {
System.out.println("Disconnecting from MySQL database");
// 实际的断开连接代码
}
}
// Oracle数据库连接
public class OracleConnection implements DatabaseConnection {
@Override
public void connect() {
System.out.println("Connecting to Oracle database");
// 实际的连接代码
}
@Override
public void disconnect() {
System.out.println("Disconnecting from Oracle database");
// 实际的断开连接代码
}
}
// SQL Server数据库连接
public class SQLServerConnection implements DatabaseConnection {
@Override
public void connect() {
System.out.println("Connecting to SQL Server database");
// 实际的连接代码
}
@Override
public void disconnect() {
System.out.println("Disconnecting from SQL Server database");
// 实际的断开连接代码
}
}
接下来,我们定义抽象工厂接口DatabaseConnectionFactory
和具体的工厂实现类。
// 抽象数据库连接工厂接口
public interface DatabaseConnectionFactory {
DatabaseConnection createConnection();
}
// MySQL数据库连接工厂
public class MySQLConnectionFactory implements DatabaseConnectionFactory {
@Override
public DatabaseConnection createConnection() {
return new MySQLConnection();
}
}
// Oracle数据库连接工厂
public class OracleConnectionFactory implements DatabaseConnectionFactory {
@Override
public DatabaseConnection createConnection() {
return new OracleConnection();
}
}
// SQL Server数据库连接工厂
public class SQLServerConnectionFactory implements DatabaseConnectionFactory {
@Override
public DatabaseConnection createConnection() {
return new SQLServerConnection();
}
}
在客户端代码中,我们可以根据需要选择不同的数据库连接工厂来创建数据库连接。
public class Client {
public static void main(String[] args) {
// 使用MySQL数据库连接工厂创建连接
DatabaseConnectionFactory mysqlFactory = new MySQLConnectionFactory();
DatabaseConnection mysqlConnection = mysqlFactory.createConnection();
mysqlConnection.connect();
// 进行数据库操作
mysqlConnection.disconnect();
// 使用Oracle数据库连接工厂创建连接
DatabaseConnectionFactory oracleFactory = new OracleConnectionFactory();
DatabaseConnection oracleConnection = oracleFactory.createConnection();
oracleConnection.connect();
// 进行数据库操作
oracleConnection.disconnect();
// 使用SQL Server数据库连接工厂创建连接
DatabaseConnectionFactory sqlServerFactory = new SQLServerConnectionFactory();
DatabaseConnection sqlServerConnection = sqlServerFactory.createConnection();
sqlServerConnection.connect();
// 进行数据库操作
sqlServerConnection.disconnect();
}
}
通过这种方式,当我们需要切换数据库类型或者添加新的数据库类型时,只需要创建新的具体数据库连接类和对应的工厂类,而不需要修改客户端代码中使用数据库连接的部分,提高了代码的可维护性和可扩展性。
六、最佳实践建议
在实际应用工厂方法模式时,以下是一些最佳实践建议,可以帮助你更好地发挥该模式的优势,提升代码的质量和可维护性。
6.1 优先使用接口作为抽象工厂
在定义抽象工厂时,优先使用接口而不是抽象类。接口具有更高的灵活性和扩展性,它可以让不同的具体工厂类实现该接口,从而方便地扩展不同的实现。例如,在上述图形绘制系统中,我们定义了ShapeFactory
接口,CircleFactory
和RectangleFactory
等具体工厂类实现了该接口。这样,当我们需要添加新的图形类型时,只需要创建一个新的具体工厂类实现ShapeFactory
接口即可,而不需要修改抽象工厂的代码。
6.2 结合配置文件
为了使系统更加灵活和可配置,可以结合配置文件来动态加载具体工厂类。通过在配置文件中指定要使用的具体工厂类的名称,然后利用反射机制根据配置文件中的信息创建具体工厂对象。这样,在系统运行时,可以通过修改配置文件来切换具体工厂类,而不需要修改代码并重新部署系统。例如,在一个电商系统中,可以通过配置文件来指定使用哪个数据库连接工厂,当需要切换数据库类型时,只需要修改配置文件中的数据库连接工厂类名即可,而不需要修改代码。
6.3 注意工厂类职责单一
每个具体工厂类应该只负责创建一种具体产品,遵循单一职责原则。这样可以避免工厂类的职责过于复杂,使得代码更加清晰和易于维护。如果一个工厂类负责创建多种不同类型的产品,当其中一种产品的创建逻辑发生变化时,可能会影响到其他产品的创建,增加了代码的维护难度。例如,在一个游戏开发中,应该为每个游戏角色创建一个单独的工厂类,如WarriorFactory
负责创建战士角色,MageFactory
负责创建法师角色等,而不是将所有角色的创建逻辑都放在一个工厂类中。
6.4 与单例模式结合
对于一些频繁使用且创建成本较高的工厂类,可以考虑与单例模式结合,确保在系统中只有一个工厂实例。这样可以减少对象的创建开销,提高系统的性能。例如,在一个日志系统中,日志工厂类可能会频繁地被调用以创建日志记录器对象,如果每次都创建一个新的日志工厂实例,会增加系统的开销。通过将日志工厂类实现为单例模式,可以确保在系统中只有一个日志工厂实例,提高系统的性能和资源利用率 。
七、模式对比
在创建型设计模式中,简单工厂模式、工厂方法模式和抽象工厂模式都用于对象的创建,但它们之间存在一些关键的差异,各自适用于不同的场景。下面通过表格形式对它们进行对比:
模式 | 核心差异 | 适用场景 |
---|---|---|
简单工厂 | 单一工厂类处理所有产品创建 | 产品类型较少且稳定 |
工厂方法 | 子类决定具体产品创建 | 需要频繁扩展新产品 |
抽象工厂 | 处理多产品族的创建 | 复杂产品体系 |
简单工厂模式虽然不属于 GOF 23 种设计模式之一,但它是工厂模式家族中最简单实用的模式。它由一个工厂对象决定创建出哪一种产品类的实例,工厂类通常包含一个静态的创建方法,利用条件语句(如 if-else 或 switch-case)根据传入的参数创建相应的产品对象。这种模式适用于产品类型较少且稳定的场景,因为当产品类型增加时,工厂类的创建方法中需要添加大量的条件判断语句,违背了开闭原则,导致代码维护困难。例如,在一个简单的图形绘制工具中,如果只需要绘制圆形和矩形两种图形,使用简单工厂模式可以将图形的创建逻辑集中在一个工厂类中,方便管理和维护。
工厂方法模式定义一个创建对象的接口,让实现这个接口的子类决定实例化哪个类,将对象的实例化推迟到子类中进行。它克服了简单工厂模式不符合开闭原则的缺点,当需要增加新的产品时,只需要创建新的具体产品类和对应的具体工厂类,而不需要修改抽象工厂和其他已有的具体工厂类的代码。这种模式适用于需要频繁扩展新产品的场景,例如在一个电商系统中,随着业务的发展,可能会不断添加新的商品类型,使用工厂方法模式可以方便地扩展商品类型,而不会对现有代码造成较大的影响。
抽象工厂模式围绕一个超级工厂创建其他工厂,该超级工厂又称为其他工厂的工厂。它提供了一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。在抽象工厂模式中,客户端通过抽象工厂接口获取具体工厂对象,然后使用具体工厂对象创建所需的产品对象。这种模式适用于复杂产品体系,例如在一个游戏开发中,可能存在多个产品族,如不同类型的游戏角色(战士、法师、刺客等)和不同类型的游戏装备(武器、防具、饰品等),每个产品族中的产品对象之间存在一定的关联或依赖关系,使用抽象工厂模式可以方便地创建和管理这些产品对象 。
八、总结
工厂方法模式通过将对象创建逻辑延迟到子类,实现了系统的高扩展性和低耦合。在实际开发中,建议:1. 需要扩展新产品时优先使用工厂方法
2. 简单场景可先用简单工厂,再重构为工厂方法
3. 复杂系统可结合抽象工厂模式使用掌握工厂方法模式,能显著提升代码的可维护性和可扩展性。你在哪些场景中使用过工厂方法模式?欢迎在评论区分享!