首页 > 基础资料 博客日记

设计模式-工厂模式

2025-06-22 02:00:02基础资料围观9

这篇文章介绍了设计模式-工厂模式,分享给大家做个参考,收藏Java资料网收获更多编程知识

什么是工厂模式?

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

一、核心思想

  • 将对象创建逻辑封装在工厂类中,客户端无需直接实例化对象,而是通过工厂获取。
  • 遵循依赖倒置原则:依赖抽象而非具体实现。

二、工厂模式的三种形态

1. 简单工厂(Simple Factory)

  • 特点:静态工厂方法,创建逻辑集中在一个工厂类。
  • 缺点:不符合开闭原则,新增产品需修改工厂类。

2. 工厂方法(Factory Method)

  • 特点:定义抽象工厂接口,具体产品由子类工厂创建。
  • 优点:符合开闭原则,新增产品只需添加新的工厂子类。

3. 抽象工厂(Abstract Factory)

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

工厂模式的优缺点

  • 优点
  1. 解耦对象创建和使用:客户端只需关注接口,无需关心具体实现。
  2. 符合开闭原则:工厂方法模式中,新增产品只需扩展工厂子类。
  3. 便于维护和扩展:创建逻辑集中,修改时只需调整工厂类。
  4. 利于代码复用:工厂类可被多个客户端复用。
  • 缺点
  1. 类数量增加:每个产品都可能需要对应的工厂类,导致代码结构复杂。
  2. 抽象层级提高:需要理解抽象工厂和具体工厂的关系,增加学习成本。
  3. 过度设计风险:简单场景下使用工厂模式可能增加不必要的复杂度。

什么场景下使用工厂模式

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

代码举例

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

  1. 简单工厂

    举例一个实际开发中用的场景,用户上传文件,但是文件涉及多种,比如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();
        }
    }
    
  2. 工厂方法:

    以读数据为例子,读数据可能从数据库里读、文件里读、还有一些非关系型数据库中读,就用工厂方法设计下边程序,就用上边的例子继续拓展了

    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();
    }
    
  3. 抽象工厂

    继续上边的设计,以读取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的生命周期,不同类型的类统一封装起来,为了代码的解偶。


文章来源:https://www.cnblogs.com/MaC-Matthew/p/18941089
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!

标签:

上一篇:设计模式-单例模式
下一篇:没有了

相关文章

本站推荐

标签云