【设计模式】工厂模式
概念
创建对象的过程与使用对象的过程分离
工厂模式是 Java 中最常用的创建型设计模式之一。它的核心思想是:将对象的创建与使用分离,通过一个“工厂”类来负责创建对象,而不是在客户端代码中直接使用 new 关键字。这样做可以降低耦合,提高代码的可维护性和扩展性。
简单工厂模式
简单工厂模式不是一个正式的设计模式,但它是工厂模式的基础。它通过一个工厂类,根据传入的参数决定创建哪种具体产品类的实例。
例如下面的代码,创建不同类型的日志记录器(文件日志、数据库日志),客户端传入的是 file 就调用 FileLogger() ,传入的是 db 就调用DatabaseLogger()。此时客户端无需知道具体产品类名,只需传入参数即可得到所需对象。
// 抽象产品
public interface Logger {
void log(String message);
}
// 具体产品1:文件日志
public class FileLogger implements Logger {
@Override
public void log(String message) {
System.out.println("写入文件:" + message);
}
}
// 具体产品2:数据库日志
public class DatabaseLogger implements Logger {
@Override
public void log(String message) {
System.out.println("写入数据库:" + message);
}
}
// 工厂类
public class LoggerFactory {
public static Logger getLogger(String type) {
if ("file".equalsIgnoreCase(type)) {
return new FileLogger();
} else if ("db".equalsIgnoreCase(type)) {
return new DatabaseLogger();
} else {
throw new IllegalArgumentException("未知日志类型");
}
}
}
// 客户端使用
public class Client {
public static void main(String[] args) {
Logger logger = LoggerFactory.getLogger("file");
logger.log("Hello World");
}
}
工厂方法模式
工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类的实例化延迟到子类。
这种模式符合开闭原则,新增产品时只需增加新的具体工厂类,无需修改已有代码;将产品创建的逻辑封装在具体工厂中,单一职责。
// 抽象产品
public interface Logger {
void log(String message);
}
// 具体产品
public class FileLogger implements Logger {
@Override
public void log(String message) {
System.out.println("写入文件:" + message);
}
}
public class DatabaseLogger implements Logger {
@Override
public void log(String message) {
System.out.println("写入数据库:" + message);
}
}
// 抽象工厂
public abstract class LoggerFactory {
// 工厂方法
public abstract Logger createLogger();
// 也可以包含其他业务方法,比如记录日志
public void log(String message) {
Logger logger = createLogger();
logger.log(message);
}
}
// 具体工厂1:文件日志工厂
public class FileLoggerFactory extends LoggerFactory {
@Override
public Logger createLogger() {
// 可以在这里添加创建文件日志的复杂逻辑
return new FileLogger();
}
}
// 具体工厂2:数据库日志工厂
public class DatabaseLoggerFactory extends LoggerFactory {
@Override
public Logger createLogger() {
// 可以在这里添加创建数据库日志的复杂逻辑
return new DatabaseLogger();
}
}
// 客户端使用
public class Client {
public static void main(String[] args) {
LoggerFactory factory = new FileLoggerFactory();
factory.log("Hello World");
factory = new DatabaseLoggerFactory();
factory.log("Hello Database");
}
}

抽象工厂模式
抽象工厂模式提供一个接口,用于创建一系列相关或相互依赖的对象,而无需指定它们具体的类。它通常用于产品族(一组具有相同主题的产品)的创建。
假设要开发一个跨平台的 UI 组件库,支持 Windows 和 Mac 风格。该模式可以确保客户端创建的产品是同一产品族,避免产品不匹配;易于交换产品族,只需更改具体工厂;符合开闭原则,增加新产品族时无需修改已有代码。
// 抽象产品:按钮
public interface Button {
void paint();
}
// 抽象产品:文本框
public interface TextField {
void display();
}
// 具体产品:Windows 按钮
public class WindowsButton implements Button {
@Override
public void paint() {
System.out.println("渲染 Windows 风格按钮");
}
}
// 具体产品:Mac 按钮
public class MacButton implements Button {
@Override
public void paint() {
System.out.println("渲染 Mac 风格按钮");
}
}
// 具体产品:Windows 文本框
public class WindowsTextField implements TextField {
@Override
public void display() {
System.out.println("显示 Windows 风格文本框");
}
}
// 具体产品:Mac 文本框
public class MacTextField implements TextField {
@Override
public void display() {
System.out.println("显示 Mac 风格文本框");
}
}
// 抽象工厂
public interface GUIFactory {
Button createButton();
TextField createTextField();
}
// 具体工厂:Windows 风格工厂
public class WindowsFactory implements GUIFactory {
@Override
public Button createButton() {
return new WindowsButton();
}
@Override
public TextField createTextField() {
return new WindowsTextField();
}
}
// 具体工厂:Mac 风格工厂
public class MacFactory implements GUIFactory {
@Override
public Button createButton() {
return new MacButton();
}
@Override
public TextField createTextField() {
return new MacTextField();
}
}
// 客户端使用
public class Application {
private Button button;
private TextField textField;
public Application(GUIFactory factory) {
button = factory.createButton();
textField = factory.createTextField();
}
public void render() {
button.paint();
textField.display();
}
public static void main(String[] args) {
// 根据操作系统或其他配置选择具体工厂
String os = "Windows"; // 假设从配置读取
GUIFactory factory;
if ("Windows".equalsIgnoreCase(os)) {
factory = new WindowsFactory();
} else {
factory = new MacFactory();
}
Application app = new Application(factory);
app.render();
}
}

对比
| 模式 | 特点 | 适用场景 |
|---|---|---|
| 简单工厂 | 一个工厂类根据参数返回不同产品,创建逻辑集中 | 产品种类较少,且不经常变化 |
| 工厂方法 | 定义创建对象的接口,由子类决定具体实例化哪个类 | 产品类型较多,且希望扩展时符合开闭原则 |
| 抽象工厂 | 创建一组相关产品对象,强调产品族 | 系统需要独立于产品创建、组合和表示,且需要配置多个产品系列 |
工厂模式在实际开发中的应用
-
Spring IoC 容器:本质上是一个超级工厂,负责创建和管理 Bean。
-
JDBC 的 DriverManager:通过 getConnection() 方法返回不同的数据库连接。
-
日志框架:如 SLF4J 结合 Logback 或 Log4j,通过工厂获取不同日志实现。
-
Java 标准库:如 Calendar.getInstance() 返回不同地区/时区的日历实例。
更多推荐
所有评论(0)