当前位置: 首页 > article >正文

重生之我在Java世界------学工厂设计模式

文章目录

    • 为什么需要工厂模式?
    • 简单工厂模式:第一步改进
    • 实际应用场景(常见场景)
      • 1. 数据库连接的创建
      • 2. 支付方式的处理
    • 工厂模式的优势
    • 注意事项
    • 总结

在日常开发工作中,我们经常需要创建对象。随着项目的发展,对象创建的逻辑可能变得越来越复杂,如果不加以良好的设计,代码很快就会变得混乱且难以维护。这时候,工厂模式就能派上用场了。

为什么需要工厂模式?

想象你去麦当劳点餐。作为顾客,你只需要说"我要一个巨无霸",服务员就会帮你准备好汉堡。你不需要关心这个汉堡是怎么做的,需要什么原料,谁来烤肉饼,怎么组装 - 这些都是麦当劳后厨(工厂)的事情。这就是工厂模式的核心思想: 你只需要告诉工厂你要什么,工厂负责帮你生产出来。

想象一下这个场景:你正在开发一个文档处理系统,需要处理不同类型的文件(PDF、Word、Excel等)。最初的代码可能是这样的:

public class DocumentProcessor {
    public void processFile(String fileType, String filePath) {
        if (fileType.equals("PDF")) {
            PDFDocument doc = new PDFDocument(filePath);
            doc.read();
            doc.process();
        } else if (fileType.equals("WORD")) {
            WordDocument doc = new WordDocument(filePath);
            doc.read();
            doc.process();
        } else if (fileType.equals("EXCEL")) {
            ExcelDocument doc = new ExcelDocument(filePath);
            doc.read();
            doc.process();
        }
    }
}

这段代码存在几个明显的问题:

  1. 每次添加新的文档类型都需要修改这个方法
  2. 对象创建的逻辑和业务逻辑混在一起
  3. 违反了开闭原则,对修改开放,对扩展关闭

简单工厂模式:第一步改进

让我们用简单工厂模式来改进这段代码。首先,我们定义一个文档处理的接口:

public interface Document {
    void read();
    void process();
}

public class PDFDocument implements Document {
    private String filePath;
    
    public PDFDocument(String filePath) {
        this.filePath = filePath;
    }
    
    @Override
    public void read() {
        System.out.println("Reading PDF file: " + filePath);
    }
    
    @Override
    public void process() {
        System.out.println("Processing PDF file");
    }
}

// WordDocument和ExcelDocument的实现类似,这里省略

然后创建一个文档工厂类:

public class DocumentFactory {
    public static Document createDocument(String fileType, String filePath) {
        if (fileType.equals("PDF")) {
            return new PDFDocument(filePath);
        } else if (fileType.equals("WORD")) {
            return new WordDocument(filePath);
        } else if (fileType.equals("EXCEL")) {
            return new ExcelDocument(filePath);
        }
        throw new IllegalArgumentException("Unsupported file type: " + fileType);
    }
}

现在,我们的文档处理类就可以简化为:

public class DocumentProcessor {
    public void processFile(String fileType, String filePath) {
        Document doc = DocumentFactory.createDocument(fileType, filePath);
        doc.read();
        doc.process();
    }
}

实际应用场景(常见场景)

1. 数据库连接的创建

不同类型数据库连接的创建就是一个典型的例子:

public class DatabaseFactory {
    public static Database createDatabase(String dbType, String connectionString) {
        switch (dbType) {
            case "MySQL":
                return new MySQLDatabase(connectionString);
            case "PostgreSQL":
                return new PostgreSQLDatabase(connectionString);
            case "MongoDB":
                return new MongoDatabase(connectionString);
            default:
                throw new IllegalArgumentException("Unsupported database type");
        }
    }
}

2. 支付方式的处理

在电商系统中,处理不同的支付方式:

public class PaymentFactory {
    public static PaymentProcessor createPaymentProcessor(String paymentMethod) {
        switch (paymentMethod) {
            case "ALIPAY":
                return new AlipayProcessor();
            case "WECHAT":
                return new WeChatPayProcessor();
            case "CREDIT_CARD":
                return new CreditCardProcessor();
            default:
                throw new IllegalArgumentException("Unsupported payment method");
        }
    }
}

工厂模式的优势

通过上面的示例,我们可以看到工厂模式带来的几个明显优势:

解耦性:对象的创建与使用分离,客户端代码不需要知道具体类的创建细节。

可维护性:所有对象创建的逻辑都集中在一处,便于统一管理和修改。

可扩展性:添加新的类型时,只需要修改工厂类,不需要修改现有的业务代码。

注意事项

虽然简单工厂模式使用方便,但也要注意以下几点:

  1. 工厂类的职责相对较重,包含了所有对象的创建逻辑,在类型非常多的情况下可能需要考虑拆分。

  2. 添加新产品时仍然需要修改工厂类的代码,这一点上违反了开闭原则。在产品类型经常变动的场景下,可能需要考虑使用工厂方法模式或抽象工厂模式。

  3. 需要注意异常处理,对于不支持的类型要给出合适的错误提示。

总结

简单工厂模式是一种应用广泛的设计模式,它通过将对象创建的逻辑封装在工厂类中,实现了对象创建和使用的解耦。在实际开发中,简单工厂模式常常是重构的第一步,它为后续可能的扩展打下了良好的基础。

虽然简单工厂模式可能违反开闭原则,但在变化相对较小的系统中,它的简单性和实用性使它成为了一个很好的选择。在实际应用中,我们需要根据具体场景来权衡是否使用简单工厂模式,或是选择更复杂的工厂方法模式、抽象工厂模式。


http://www.kler.cn/a/378834.html

相关文章:

  • 【linux】HTTPS 协议原理
  • Vehicle OS软件平台解决方案
  • ubuntu22.04安装conda
  • 电子电气架构 --- 车载诊断的快速入门
  • ELK的ElasticStack语法
  • 使用ffmpeg和mediamtx模拟多通道rtsp相机
  • Transformer 架构简单理解;GPT-3.5 的架构,向量长度为 :12288;Transformer架构改进:BERT和GPT
  • git创建一个公共子模块用于不同的项目共享这一个子模块
  • JWT-混淆算法
  • 鸿蒙HarmonyOS应用开发者(基础+高级)认证
  • uniapp下载文件的方案,包括H5,App方案解决办法
  • 如何使用Python WebDriver爬取ChatGPT内容(完整教程)
  • 数据结构,问题 C: 后缀表达式
  • Java NIO 【处理消息边界】
  • 基于 Spring Boot 和 Vue 的大学生入伍管理创新系统
  • CSS中display和visibility的区别
  • pnpm install安装element-plus的版本跟package.json指定的版本不一样
  • Hive SQL 和 SQL 的区别总结(持续更新中.....)
  • UV紫外相机
  • 在 C/C++ 之中为什么应该建议使用C函数库定义的基础数值类型,而不是编译默认的关键字类型?
  • Javase——正则表达式
  • C#开发webService接口
  • aws(学习笔记第九课) 使用AWS的网络存储EBS
  • Git 概述及相关命令(1)
  • 【小白学机器学习28】 统计学脉络+ 总体+ 随机抽样方法
  • 【Git】Git 版本控制与协作开发指南