主要区别
- 定义与意图:
- 工厂方法模式:定义一个创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
- 抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
- 结构复杂度:
- 工厂方法模式:结构相对简单,只有一个抽象产品类和一个具体产品类层次结构,工厂类有一个抽象创建方法,具体工厂类实现该方法创建具体产品。
- 抽象工厂模式:结构更复杂,有多个抽象产品类和具体产品类层次结构,抽象工厂类有多个创建不同类型产品的抽象方法,具体工厂类实现这些方法创建一系列相关产品。
- 灵活性与可维护性:
- 工厂方法模式:当需要新增一种产品时,只需新增一个具体产品类和一个对应的具体工厂类,符合开闭原则,灵活性较好,维护相对容易。
- 抽象工厂模式:当需要新增一种产品时,需要修改抽象工厂接口及所有具体工厂类,违反开闭原则,灵活性和维护性较差,但对于创建一组相关产品非常方便。
- 创建对象的粒度:
- 工厂方法模式:每次创建一个具体产品对象。
- 抽象工厂模式:每次创建一系列相关的产品对象。
应用场景举例
- 工厂方法模式应用场景:
- 日志记录系统:不同的日志记录方式如文件日志、数据库日志等。定义一个抽象的日志记录工厂类,有一个抽象的创建日志记录器方法。具体的文件日志工厂类实现该方法创建文件日志记录器,数据库日志工厂类实现该方法创建数据库日志记录器。
- 代码示例:
// 抽象产品类
abstract class Logger {
public abstract void log(String message);
}
// 具体产品类1
class FileLogger extends Logger {
@Override
public void log(String message) {
System.out.println("Logging to file: " + message);
}
}
// 具体产品类2
class DatabaseLogger extends Logger {
@Override
public void log(String message) {
System.out.println("Logging to database: " + message);
}
}
// 抽象工厂类
abstract class LoggerFactory {
public abstract Logger createLogger();
}
// 具体工厂类1
class FileLoggerFactory extends LoggerFactory {
@Override
public Logger createLogger() {
return new FileLogger();
}
}
// 具体工厂类2
class DatabaseLoggerFactory extends LoggerFactory {
@Override
public Logger createLogger() {
return new DatabaseLogger();
}
}
// 使用示例
public class Main {
public static void main(String[] args) {
LoggerFactory fileLoggerFactory = new FileLoggerFactory();
Logger fileLogger = fileLoggerFactory.createLogger();
fileLogger.log("This is a file log message");
LoggerFactory databaseLoggerFactory = new DatabaseLoggerFactory();
Logger databaseLogger = databaseLoggerFactory.createLogger();
databaseLogger.log("This is a database log message");
}
}
- 抽象工厂模式应用场景:
- 跨平台UI组件创建:在不同的操作系统(如Windows、MacOS)上创建不同风格的UI组件,如按钮、文本框等。定义一个抽象工厂类,有创建按钮和文本框的抽象方法。具体的Windows工厂类实现这些方法创建Windows风格的按钮和文本框,MacOS工厂类实现这些方法创建MacOS风格的按钮和文本框。
- 代码示例:
// 抽象产品类1:按钮
abstract class Button {
public abstract void render();
}
// 具体产品类1.1:Windows按钮
class WindowsButton extends Button {
@Override
public void render() {
System.out.println("Rendering a Windows button");
}
}
// 具体产品类1.2:MacOS按钮
class MacOSButton extends Button {
@Override
public void render() {
System.out.println("Rendering a MacOS button");
}
}
// 抽象产品类2:文本框
abstract class TextField {
public abstract void render();
}
// 具体产品类2.1:Windows文本框
class WindowsTextField extends TextField {
@Override
public void render() {
System.out.println("Rendering a Windows text field");
}
}
// 具体产品类2.2:MacOS文本框
class MacOSTextField extends TextField {
@Override
public void render() {
System.out.println("Rendering a MacOS text field");
}
}
// 抽象工厂类
abstract class GUIFactory {
public abstract Button createButton();
public abstract TextField createTextField();
}
// 具体工厂类1:Windows工厂
class WindowsGUIFactory extends GUIFactory {
@Override
public Button createButton() {
return new WindowsButton();
}
@Override
public TextField createTextField() {
return new WindowsTextField();
}
}
// 具体工厂类2:MacOS工厂
class MacOSGUIFactory extends GUIFactory {
@Override
public Button createButton() {
return new MacOSButton();
}
@Override
public TextField createTextField() {
return new MacOSTextField();
}
}
// 使用示例
public class Main {
public static void main(String[] args) {
GUIFactory windowsFactory = new WindowsGUIFactory();
Button windowsButton = windowsFactory.createButton();
TextField windowsTextField = windowsFactory.createTextField();
windowsButton.render();
windowsTextField.render();
GUIFactory macOSFactory = new MacOSGUIFactory();
Button macOSButton = macOSFactory.createButton();
TextField macOSTextField = macOSFactory.createTextField();
macOSButton.render();
macOSTextField.render();
}
}