设计模式-工厂模式

[复制链接]
发表于 2025-6-22 01:37:22 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
什么是工厂模式?

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

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

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

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

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


  • 优点

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


  • 缺点

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


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

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

  • 简朴工厂:
    举例一个实际开发中用的场景,用户上传文件,但是文件涉及多种,好比flat文件、Excel、json、xml文件,上传的文件读取内容,下边就用工厂模式来设计
    1. interface FileItemReader<T>{
    2.     List<T> read();
    3. }
    4.    
    5. class FlatFileItemReader<T> implements FileItemReader<T>{
    6.   @Override
    7.   public List<T> read() {
    8.     return null;
    9.   }
    10. }
    11. class ExcelItemReader<T> implements FileItemReader<T>{
    12.   @Override
    13.   public List<T> read() {
    14.     return null;
    15.   }
    16. }
    17. class JsonFileItemReader<T> implements FileItemReader<T>{
    18.   @Override
    19.   public List<T> read() {
    20.     return null;
    21.   }
    22. }
    23. class FileItemReaderFactory<T>{
    24.   public FileItemReader<T> createFileItemReader(String fileName){
    25.     if(fileName.endsWith("csv") || fileName.endsWith("txt")){
    26.       return new FlatFileItemReader<>();
    27.     }else if(fileName.endsWith("xlsx") || fileName.endsWith("xls")){
    28.       return new ExcelItemReader<>();
    29.     }else if(fileName.endsWith("json")){
    30.       return new JsonFileItemReader<>();
    31.     }else {
    32.       throw new IllegalArgumentException("不支持的文件类型");
    33.     }
    34.   }
    35. }
    36. public class FactoryDemo {
    37.     public static void main(String[] args) {
    38.         String fileName = "test.xlsx";
    39.         FileItemReaderFactory<ReadTestEntity> factory = new FileItemReaderFactory<>();
    40.         FileItemReader<ReadTestEntity> fileItemReader = factory.createFileItemReader(fileName);
    41.         List<ReadTestEntity> read = fileItemReader.read();
    42.     }
    43. }
    复制代码
  • 工厂方法:
    以读数据为例子,读数据大概从数据库里读、文件里读、还有一些非关系型数据库中读,就用工厂方法设计下边程序,就用上边的例子继续拓展了
    1. interface ItemReader<T> {
    2. List<T> read();
    3. }
    4. interface FileItemReader<T> extends ItemReader<T> {
    5. }
    6. class FlatFileItemReader<T> implements FileItemReader<T> {
    7.   @Override
    8.   public List<T> read() {
    9.     return null;
    10.   }
    11. }
    12. class ExcelItemReader<T> implements FileItemReader<T> {
    13.   @Override
    14.   public List<T> read() {
    15.     return null;
    16.   }
    17. }
    18. class JsonFileItemReader<T> implements FileItemReader<T> {
    19.   @Override
    20.   public List<T> read() {
    21.     return null;
    22.   }
    23. }
    24. interface JdbcItemReader<T> extends ItemReader<T> {
    25. }
    26. class JdbcCursorItemReader<T> implements JdbcItemReader<T> {
    27.   @Override
    28.   public List<T> read() {
    29.     return null;
    30.   }
    31. }
    32. class HibernateItemReader<T> implements JdbcItemReader<T> {
    33.   @Override
    34.   public List<T> read() {
    35.     return null;
    36.   }
    37. }
    38. interface Creator<T> {
    39.   ItemReader<T> create(String type);
    40. }
    41. class FileItemReaderFactory<T> implements Creator<T> {
    42.   @Override
    43.   public ItemReader<T> create(String fileName) {
    44.     if (fileName.endsWith("csv") || fileName.endsWith("txt")) {
    45.       return new FlatFileItemReader<>();
    46.     } else if (fileName.endsWith("xlsx") || fileName.endsWith("xls")) {
    47.       return new ExcelItemReader<>();
    48.     } else if (fileName.endsWith("json")) {
    49.       return new JsonFileItemReader<>();
    50.     } else {
    51.       throw new IllegalArgumentException("不支持的文件类型");
    52.     }
    53.   }
    54. }
    55. class JdbcItemReaderFactory<T> implements Creator<T> {
    56.   @Override
    57.   public ItemReader<T> create(String type) {
    58.     if(type.equals("jdbc")){
    59.       return new JdbcCursorItemReader<>();
    60.     }else if (type.equals("hibernate")){
    61.       return new HibernateItemReader<>();
    62.     }else {
    63.       throw new IllegalArgumentException("不支持的文件类型");
    64.     }
    65.   }
    66. }
    67. public static void main(String[] args) {
    68.         String fileName = "test.xlsx";
    69.         Creator<ReadTestEntity> creator = new FileItemReaderFactory<>();
    70.         List<ReadTestEntity> read = creator.create(fileName).read();
    71. }
    复制代码
  • 抽象工厂
    继续上边的设计,以读取flat范例文件为例,读取文件时间必要获取不同的流,也必要不同的数据映射关系,这里用抽象工厂就很符合
    1. interface ItemReader<T> {
    2.   List<T> read();
    3. }
    4. interface FileItemReader<T> extends ItemReader<T> {
    5. }
    6. class FlatFileItemReader<T> implements FileItemReader<T> {
    7.   private final BufferReaderFactory bufferReaderFactory;
    8.   private final BeanMappingFactory beanMappingFactory;
    9.   public FlatFileItemReader(BufferReaderFactory bufferReaderFactory, BeanMappingFactory beanMappingFactory) {
    10.     this.bufferReaderFactory = bufferReaderFactory;
    11.     this.beanMappingFactory = beanMappingFactory;
    12.   }
    13.   @Override
    14.   public List<T> read() {
    15.     return null;
    16.   }
    17. }
    18. class ExcelItemReader<T> implements FileItemReader<T> {
    19.   @Override
    20.   public List<T> read() {
    21.     return null;
    22.   }
    23. }
    24. class JsonFileItemReader<T> implements FileItemReader<T> {
    25.   @Override
    26.   public List<T> read() {
    27.     return null;
    28.   }
    29. }
    30. interface JdbcItemReader<T> extends ItemReader<T> {
    31. }
    32. class JdbcCursorItemReader<T> implements JdbcItemReader<T> {
    33.   @Override
    34.   public List<T> read() {
    35.     return null;
    36.   }
    37. }
    38. class HibernateItemReader<T> implements JdbcItemReader<T> {
    39.   @Override
    40.   public List<T> read() {
    41.     return null;
    42.   }
    43. }
    44. interface Creator<T> {
    45.   ItemReader<T> create(String type);
    46. }
    47. class FileItemReaderFactory<T> implements Creator<T> {
    48.   private final BufferReaderFactory bufferReaderFactory;
    49.   private final BeanMappingFactory beanMappingFactory;
    50.   public FileItemReaderFactory(BufferReaderFactory bufferReaderFactory, BeanMappingFactory beanMappingFactory) {
    51.     this.bufferReaderFactory = bufferReaderFactory;
    52.     this.beanMappingFactory = beanMappingFactory;
    53.   }
    54.   @Override
    55.   public ItemReader<T> create(String fileName) {
    56.     if (fileName.endsWith("csv") || fileName.endsWith("txt")) {
    57.       return new FlatFileItemReader<>(bufferReaderFactory, beanMappingFactory);
    58.     } else if (fileName.endsWith("xlsx") || fileName.endsWith("xls")) {
    59.       return new ExcelItemReader<>();
    60.     } else if (fileName.endsWith("json")) {
    61.       return new JsonFileItemReader<>();
    62.     } else {
    63.       throw new IllegalArgumentException("不支持的数据库读取类型");
    64.     }
    65.   }
    66. }
    67. class JdbcItemReaderFactory<T> implements Creator<T> {
    68.   @Override
    69.   public ItemReader<T> create(String type) {
    70.     if(type.equals("jdbc")){
    71.       return new JdbcCursorItemReader<>();
    72.     }else if (type.equals("hibernate")){
    73.       return new HibernateItemReader<>();
    74.     }else {
    75.       throw new IllegalArgumentException("不支持的数据库读取类型");
    76.     }
    77.   }
    78. }
    79. interface BufferReaderFactory {
    80.   BufferedReader create(Resource resource, String encoding);
    81. }
    82. interface BeanMappingFactory {
    83.   BeanPropertyMap create(Class<?> clazz, String lineData);
    84. }
    85.    
    86. public static void main(String[] args) {
    87.         String fileName = "test.xlsx";
    88.         Creator<ReadTestEntity> creator = new FileItemReaderFactory<>();
    89.         List<ReadTestEntity> read = creator.create(fileName).read();
    90. }
    复制代码
总结

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

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表