设计模式之工厂方法模式

工厂方法模式(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. 工厂方法模式与其他模式的结合

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

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

五、总结

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

相关推荐
·云扬·3 小时前
Java IO 与 BIO、NIO、AIO 详解
java·开发语言·笔记·学习·nio·1024程序员节
求积分不加C3 小时前
Spring Boot中使用AOP和反射机制设计一个的幂等注解(两种持久化模式),简单易懂教程
java·spring boot·后端
枫叶_v3 小时前
【SpringBoot】26 实体映射工具(MapStruct)
java·spring boot·后端
东方巴黎~Sunsiny3 小时前
java-图算法
java·开发语言·算法
2401_857617624 小时前
汽车资讯新趋势:Spring Boot技术解读
java·spring boot·后端
小林学习编程5 小时前
从零开始理解Spring Security的认证与授权
java·后端·spring
写bug的羊羊5 小时前
Spring Boot整合Nacos启动时 Failed to rename context [nacos] as [xxx]
java·spring boot·后端
努力的小陈^O^5 小时前
docker学习笔记跟常用命令总结
java·笔记·docker·云原生
童先生5 小时前
如何将java项目打包成docker 镜像并且可运行
java·开发语言·docker
feilieren5 小时前
SpringBoot 2.x 整合 Redis
java·开发语言·spring