设计模式之工厂方法模式

工厂方法模式(Factory Method Pattern) 是设计模式中的一种创建型模式,它定义了一个用于创建对象的接口,但让子类决定要实例化的类是哪一个。工厂方法让类的实例化推迟到子类中进行。工厂方法模式是一种非常实用的模式,特别是在处理大量具有共同接口的类时,系统要基于多个扩展类的类型来决定实例化哪一个类。

一、工厂方法模式概述

1. 模式动机

在软件系统中,经常面临着"某个对象"的创建工作,由于需求的变化,这个对象的创建逻辑可能经常变化,但它却拥有比较稳定的接口。如何应对这种变化?如何设计出满足需求的类结构?工厂方法模式提供了一种解决方案。

2. 模式定义

工厂方法模式(Factory Method Pattern)又称为多态性工厂模式,它属于类创建型模式。在工厂方法模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象,这样做的目的是将产品类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定究竟应该实例化哪一个具体产品类。

3. 模式结构

工厂方法模式包含以下四个角色:

Product(抽象产品):定义产品的接口,是工厂方法模式所创建对象的超类型,也就是产品对象的共同父类或接口。

ConcreteProduct(具体产品):实现了抽象产品接口的具体产品对象,被具体的工厂类所创建。

Creator(抽象工厂):声明了工厂方法(Factory Method),用于返回一个产品。工厂方法是一个返回抽象产品类型的方法,其子类可以覆盖该方法以返回不同的具体产品类型。

ConcreteCreator(具体工厂):实现了抽象工厂中的工厂方法,通过客户调用以返回具体产品类的实例。

4. 优缺点

优点:

用户只需要知道具体工厂类的名称就可得到所要的产品,无须知道产品的具体创建过程。

灵活性增强,对于新产品的创建,只需继承一个具体工厂类或者添加一个具体工厂类,就可以实现扩展。

缺点:

类的个数容易过多,增加系统的复杂度,因为每增加一个产品,就需要增加一个具体产品类和一个具体工厂类。

系统扩展繁琐,如果要增加一个新的产品,除了增加新的产品类外,还需要增加新的具体工厂类,并在客户端中增加新的工厂类的实例。

二、工厂方法模式实现

1. 示例场景

假设我们有一个日志系统,需要支持多种日志记录方式(如文件日志、数据库日志、控制台日志等)。每种日志记录方式都有自己特定的实现,但对外都提供一个统一的接口。我们可以使用工厂方法模式来设计这个日志系统。

2. 角色定义

Log(抽象产品):定义日志记录的接口。

FileLog(具体产品):实现文件日志记录。

DatabaseLog(具体产品):实现数据库日志记录。

LogFactory(抽象工厂):声明创建日志记录的工厂方法。

FileLogFactory(具体工厂):实现创建文件日志记录的工厂。

DatabaseLogFactory(具体工厂):实现创建数据库日志记录的工厂。

3. Java代码实现

java 复制代码
// 抽象产品:日志记录接口  
interface Log {  
    void writeLog(String message);  
}  
  
// 具体产品:文件日志记录  
class FileLog implements Log {  
    @Override  
    public void writeLog(String message) {  
        System.out.println("FileLog: " + message);  
    }  
}  
  
// 具体产品:数据库日志记录  
class DatabaseLog implements Log {  
    @Override  
    public void writeLog(String message) {  
        System.out.println("DatabaseLog: " + message);  
    }  
}  
  
// 抽象工厂:日志工厂接口  
interface LogFactory {  
    Log createLog();  
}  
  
// 具体工厂:文件日志工厂  
class FileLogFactory implements LogFactory {  
    @Override  
    public Log createLog() {  
        return new FileLog();  
    }  
}  
  
// 具体工厂:数据库日志工厂  
class DatabaseLogFactory implements LogFactory {  
    @Override  
    public Log createLog() {  
        return new DatabaseLog();  
    }  
}  
  
// 客户端代码  
public class Client {  
    public static void main(String[] args) {  
        // 使用文件日志  
        LogFactory fileLogFactory = new FileLogFactory();  
        Log fileLog = fileLogFactory.createLog();  
        fileLog.writeLog("This is a file log.");  
  
        // 使用数据库日志  
        LogFactory databaseLogFactory = new DatabaseLogFactory();  
        Log databaseLog = databaseLogFactory.createLog();  
        databaseLog.writeLog("This is a database log.");  
    }  
}

三、工厂方法模式的应用场景

当一个类不知道它所必须创建的对象的类的时候。

当一个类希望由它的子类来指定它所创建的对象的时候。

当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。

四、工厂方法模式的扩展

1. 工厂方法模式的变体

简单工厂模式:简单工厂模式不属于GOF的23种设计模式之一,但它是一种非常常用的实例化对象的模式。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例,类似于一个工厂类负责创建所有实例。

抽象工厂模式:抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。

2. 工厂方法模式与其他模式的结合

与单例模式结合:在某些情况下,工厂类本身就是一个单例,负责创建和管理所有的产品对象。

与策略模式结合:工厂方法模式可以与策略模式结合使用,将不同的算法封装成不同的产品类,由工厂类根据需求创建相应的算法对象。

五、总结

工厂方法模式是一种非常实用的设计模式,它通过定义一个用于创建对象的接口,让子类决定实例化哪一个类。这种方式将对象的创建逻辑封装在工厂类中,使得客户端代码与具体的产品类解耦,提高了系统的灵活性和可扩展性。同时,工厂方法模式也具有一定的局限性,如类的个数容易过多、系统扩展繁琐等。因此,在设计系统时,需要根据实际情况选择合适的设计模式。

相关推荐
维天说1 小时前
CLI-Switch 2026年3月版历史设计:Hook、TTY 隔离与 JSON 状态
java·服务器·json
Zane19942 小时前
并发 vs 并行:别再傻傻分不清了,一文讲透 Java 并发编程的第一课
java·后端
杨充3 小时前
11.DDD与战术建模
设计模式·开源·代码规范
杨充3 小时前
12.综合实战图片框架
设计模式·开源·代码规范
噢,我明白了3 小时前
java中Excel的导入和导出(EasyExcel)
java·开发语言·excel
吠品3 小时前
Zabbix Web界面误报Server未运行的排查与解决
java·服务器·数据库
啊湘3 小时前
天气查询API接口 按月Token鉴权 实时天气 物联网可用 文档齐全
java·后端·struts
Java内核笔记4 小时前
告别十亿美元的错误 : Spring Boot 4 空安全 (JSpecify) 实战
java·spring boot·后端
糖果店的幽灵4 小时前
langgraph的 MessagesState 解读
java·开发语言·人工智能·windows·langgraph
极光代码工作室5 小时前
基于SpringBoot的在线博客系统
java·springboot·web开发·后端开发