毡轩 发表于 2025-9-25 20:55:19

设计模式-工厂模式

什么是工厂模式?

工厂模式(Factory Pattern)是一种创建型设计模式,它将对象的创建和使用分离,通过工厂类来负责创建对象。这种模式可以降低代码间的耦合度,提高可维护性和可扩展性。
一、核心思想

[*]将对象创建逻辑封装在工厂类中,客户端无需直接实例化对象,而是通过工厂获取。
[*]遵循依赖倒置原则:依赖抽象而非具体实现。
二、工厂模式的三种形态
1. 简单工厂(Simple Factory)

[*]特点:静态工厂方法,创建逻辑集中在一个工厂类。
[*]缺点:不符合开闭原则,新增产品需修改工厂类。
2. 工厂方法(Factory Method)

[*]特点:定义抽象工厂接口,具体产品由子类工厂创建。
[*]优点:符合开闭原则,新增产品只需添加新的工厂子类。
3. 抽象工厂(Abstract Factory)

[*]特点:创建产品家族,每个具体工厂负责创建一系列相关产品。
[*]适用场景:系统需要独立于产品的创建、组合和表示时。
工厂模式的优缺点


[*]优点

[*]解耦对象创建和使用:客户端只需关注接口,无需关心具体实现。
[*]符合开闭原则:工厂方法模式中,新增产品只需扩展工厂子类。
[*]便于维护和扩展:创建逻辑集中,修改时只需调整工厂类。
[*]利于代码复用:工厂类可被多个客户端复用。


[*]缺点

[*]类数量增加:每个产品都可能需要对应的工厂类,导致代码结构复杂。
[*]抽象层级提高:需要理解抽象工厂和具体工厂的关系,增加学习成本。
[*]过度设计风险:简单场景下使用工厂模式可能增加不必要的复杂度。
什么场景下使用工厂模式


[*]对复杂对象的创建:某些类在new创建完之后,并不能拥有完成的功能,需要一些参数,活在构造方法中有复杂的参数传递时,这个时候就需要用到工厂模式
[*]根据条件动态创建对象:在支付的场景下,可能有微信、支付宝、银联等多种支付方式,可以根据选择创建不同的对象
[*]统一管理对象创建逻辑:以spring为例,在bean的实例化过程中,需要统一管理bean的生命周期,涉及一整套的接口判断,逻辑校验等,这个时候也可以是工厂模式
代码举例

下边以简单工厂模式、工厂方法、抽象工厂、实例开发中怎么用举例。(这里仅仅是一个设计思路,实际开发中还需要根据功能和业务修改)

[*]简单工厂:
举例一个实际开发中用的场景,用户上传文件,但是文件涉及多种,比如flat文件、Excel、json、xml文件,上传的文件读取内容,下边就用工厂模式来设计
interface FileItemReader<T>{
    List<T> read();
}
   
class FlatFileItemReader<T> implements FileItemReader<T>{
@Override
public List<T> read() {
    return null;
}
}

class ExcelItemReader<T> implements FileItemReader<T>{
@Override
public List<T> read() {
    return null;
}
}

class JsonFileItemReader<T> implements FileItemReader<T>{
@Override
public List<T> read() {
    return null;
}
}

class FileItemReaderFactory<T>{
public FileItemReader<T> createFileItemReader(String fileName){
    if(fileName.endsWith("csv") || fileName.endsWith("txt")){
      return new FlatFileItemReader<>();
    }else if(fileName.endsWith("xlsx") || fileName.endsWith("xls")){
      return new ExcelItemReader<>();
    }else if(fileName.endsWith("json")){
      return new JsonFileItemReader<>();
    }else {
      throw new IllegalArgumentException("不支持的文件类型");
    }
}
}

public class FactoryDemo {

    public static void main(String[] args) {
      String fileName = "test.xlsx";
      FileItemReaderFactory<ReadTestEntity> factory = new FileItemReaderFactory<>();
      FileItemReader<ReadTestEntity> fileItemReader = factory.createFileItemReader(fileName);
      List<ReadTestEntity> read = fileItemReader.read();
    }
}
[*]工厂方法:
以读数据为例子,读数据可能从数据库里读、文件里读、还有一些非关系型数据库中读,就用工厂方法设计下边程序,就用上边的例子继续拓展了
interface ItemReader<T> {
List<T> read();
}

interface FileItemReader<T> extends ItemReader<T> {

}

class FlatFileItemReader<T> implements FileItemReader<T> {
@Override
public List<T> read() {
    return null;
}
}

class ExcelItemReader<T> implements FileItemReader<T> {
@Override
public List<T> read() {
    return null;
}
}

class JsonFileItemReader<T> implements FileItemReader<T> {
@Override
public List<T> read() {
    return null;
}
}

interface JdbcItemReader<T> extends ItemReader<T> {

}

class JdbcCursorItemReader<T> implements JdbcItemReader<T> {
@Override
public List<T> read() {
    return null;
}
}

class HibernateItemReader<T> implements JdbcItemReader<T> {
@Override
public List<T> read() {
    return null;
}
}

interface Creator<T> {
ItemReader<T> create(String type);
}

class FileItemReaderFactory<T> implements Creator<T> {
@Override
public ItemReader<T> create(String fileName) {
    if (fileName.endsWith("csv") || fileName.endsWith("txt")) {
      return new FlatFileItemReader<>();
    } else if (fileName.endsWith("xlsx") || fileName.endsWith("xls")) {
      return new ExcelItemReader<>();
    } else if (fileName.endsWith("json")) {
      return new JsonFileItemReader<>();
    } else {
      throw new IllegalArgumentException("不支持的文件类型");
    }
}
}

class JdbcItemReaderFactory<T> implements Creator<T> {
@Override
public ItemReader<T> create(String type) {
    if(type.equals("jdbc")){
      return new JdbcCursorItemReader<>();
    }else if (type.equals("hibernate")){
      return new HibernateItemReader<>();
    }else {
      throw new IllegalArgumentException("不支持的文件类型");
    }
}
}

public static void main(String[] args) {
      String fileName = "test.xlsx";
      Creator<ReadTestEntity> creator = new FileItemReaderFactory<>();
      List<ReadTestEntity> read = creator.create(fileName).read();
}
[*]抽象工厂
继续上边的设计,以读取flat类型文件为例,读取文件时候需要获取不同的流,也需要不同的数据映射关系,这里用抽象工厂就很合适
interface ItemReader<T> {
List<T> read();
}

interface FileItemReader<T> extends ItemReader<T> {

}

class FlatFileItemReader<T> implements FileItemReader<T> {

private final BufferReaderFactory bufferReaderFactory;
private final BeanMappingFactory beanMappingFactory;

public FlatFileItemReader(BufferReaderFactory bufferReaderFactory, BeanMappingFactory beanMappingFactory) {
    this.bufferReaderFactory = bufferReaderFactory;
    this.beanMappingFactory = beanMappingFactory;
}


@Override
public List<T> read() {
    return null;
}
}

class ExcelItemReader<T> implements FileItemReader<T> {
@Override
public List<T> read() {
    return null;
}
}

class JsonFileItemReader<T> implements FileItemReader<T> {
@Override
public List<T> read() {
    return null;
}
}

interface JdbcItemReader<T> extends ItemReader<T> {

}

class JdbcCursorItemReader<T> implements JdbcItemReader<T> {
@Override
public List<T> read() {
    return null;
}
}

class HibernateItemReader<T> implements JdbcItemReader<T> {
@Override
public List<T> read() {
    return null;
}
}

interface Creator<T> {
ItemReader<T> create(String type);
}

class FileItemReaderFactory<T> implements Creator<T> {
private final BufferReaderFactory bufferReaderFactory;
private final BeanMappingFactory beanMappingFactory;

public FileItemReaderFactory(BufferReaderFactory bufferReaderFactory, BeanMappingFactory beanMappingFactory) {
    this.bufferReaderFactory = bufferReaderFactory;
    this.beanMappingFactory = beanMappingFactory;
}

@Override
public ItemReader<T> create(String fileName) {
    if (fileName.endsWith("csv") || fileName.endsWith("txt")) {
      return new FlatFileItemReader<>(bufferReaderFactory, beanMappingFactory);
    } else if (fileName.endsWith("xlsx") || fileName.endsWith("xls")) {
      return new ExcelItemReader<>();
    } else if (fileName.endsWith("json")) {
      return new JsonFileItemReader<>();
    } else {
      throw new IllegalArgumentException("不支持的数据库读取类型");
    }
}
}

class JdbcItemReaderFactory<T> implements Creator<T> {
@Override
public ItemReader<T> create(String type) {
    if(type.equals("jdbc")){
      return new JdbcCursorItemReader<>();
    }else if (type.equals("hibernate")){
      return new HibernateItemReader<>();
    }else {
      throw new IllegalArgumentException("不支持的数据库读取类型");
    }
}
}

interface BufferReaderFactory {
BufferedReader create(Resource resource, String encoding);
}

interface BeanMappingFactory {
BeanPropertyMap create(Class<?> clazz, String lineData);
}
   
public static void main(String[] args) {
      String fileName = "test.xlsx";
      Creator<ReadTestEntity> creator = new FileItemReaderFactory<>();
      List<ReadTestEntity> read = creator.create(fileName).read();
}
总结

通过上边的举例,工厂模式其实就是将较为复杂的类创建,统一的bean的生命周期,不同类型的类统一封装起来,为了代码的解偶。

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

屠焘 发表于 2025-11-30 10:01:01

这个有用。

支智敏 发表于 2025-12-15 18:09:53

谢谢分享,辛苦了

上官泰 发表于 2025-12-24 21:38:08

喜欢鼓捣这些软件,现在用得少,谢谢分享!

觞刈 发表于 2026-1-8 16:32:40

感谢发布原创作品,程序园因你更精彩

伏滢 发表于 2026-1-19 02:21:17

前排留名,哈哈哈

赴忽 发表于 2026-1-19 10:40:38

这个好,看起来很实用

橘芜 发表于 2026-1-19 22:40:57

谢谢分享,辛苦了

届表 发表于 2026-1-20 15:07:12

这个好,看起来很实用

指陡 发表于 2026-1-21 20:58:41

过来提前占个楼

扔飒 发表于 2026-1-21 23:22:43

很好很强大我过来先占个楼 待编辑

娥搽裙 发表于 2026-1-22 13:54:22

懂技术并乐意极积无私分享的人越来越少。珍惜

峰襞副 发表于 2026-1-23 01:50:37

东西不错很实用谢谢分享

敖可 发表于 2026-1-25 12:20:59

前排留名,哈哈哈

处匈跑 发表于 2026-1-27 04:36:14

热心回复!

疝镜泛 发表于 2026-2-3 03:04:30

热心回复!

匡菲 发表于 2026-2-4 10:48:07

鼓励转贴优秀软件安全工具和文档!

处匈跑 发表于 2026-2-6 05:11:30

很好很强大我过来先占个楼 待编辑

毕余馥 发表于 2026-2-8 09:17:31

不错,里面软件多更新就更好了

暴灵珊 发表于 2026-2-8 11:14:18

鼓励转贴优秀软件安全工具和文档!
页: [1] 2
查看完整版本: 设计模式-工厂模式