设计模式之工厂方法模式

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

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

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

五、总结

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

相关推荐
阿伟*rui2 小时前
配置管理,雪崩问题分析,sentinel的使用
java·spring boot·sentinel
XiaoLeisj4 小时前
【JavaEE初阶 — 多线程】单例模式 & 指令重排序问题
java·开发语言·java-ee
paopaokaka_luck4 小时前
【360】基于springboot的志愿服务管理系统
java·spring boot·后端·spring·毕业设计
dayouziei4 小时前
java的类加载机制的学习
java·学习
Yaml46 小时前
Spring Boot 与 Vue 共筑二手书籍交易卓越平台
java·spring boot·后端·mysql·spring·vue·二手书籍
小小小妮子~6 小时前
Spring Boot详解:从入门到精通
java·spring boot·后端
hong1616886 小时前
Spring Boot中实现多数据源连接和切换的方案
java·spring boot·后端
aloha_7896 小时前
从零记录搭建一个干净的mybatis环境
java·笔记·spring·spring cloud·maven·mybatis·springboot
记录成长java7 小时前
ServletContext,Cookie,HttpSession的使用
java·开发语言·servlet
睡觉谁叫~~~7 小时前
一文解秘Rust如何与Java互操作
java·开发语言·后端·rust