设计模式之工厂方法模式

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

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

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

五、总结

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

相关推荐
JOJO___18 分钟前
Spring IoC 配置类 总结
java·后端·spring·java-ee
蜗牛学苑_武汉20 分钟前
设计模式之代理模式
java·网络·java-ee·代理模式
极客先躯30 分钟前
java和kotlin 可以同时运行吗
android·java·开发语言·kotlin·同时运行
严文文-Chris42 分钟前
【设计模式-组合】
设计模式
luoluoal1 小时前
java项目之企业级工位管理系统源码(springboot)
java·开发语言·spring boot
ch_s_t1 小时前
新峰商城之购物车(一)
java·开发语言
蜜桃小阿雯1 小时前
JAVA开源项目 校园美食分享平台 计算机毕业设计
java·jvm·spring boot·spring cloud·intellij-idea·美食
黄昏_1 小时前
苍穹外卖Day01-2
java·spring
努力的八爪鱼2 小时前
记录工作中遇到的问题(持续更新~)
java
求学小火龙2 小时前
ElasticSearch介绍+使用
java·大数据·elasticsearch