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

文章目录

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

为什么需要工厂模式?

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

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

java 复制代码
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. 违反了开闭原则,对修改开放,对扩展关闭

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

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

java 复制代码
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的实现类似,这里省略

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

java 复制代码
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);
    }
}

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

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

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

1. 数据库连接的创建

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

java 复制代码
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. 支付方式的处理

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

java 复制代码
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. 需要注意异常处理,对于不支持的类型要给出合适的错误提示。

总结

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

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

相关推荐
lulu121654407825 分钟前
OpenRouter Fusion 多模型融合架构深度拆解:预算级模型组团打平 Fable 5,多模型协作才是 AGI 的正确打开方式?
java·人工智能·架构·ai编程·agi
雨辰AI30 分钟前
生产级实测:SpringBoot3 + 达梦数据库接口从 200ms 优化至 20ms 完整调优指南
java·数据库·spring boot·后端·政务
(Charon)1 小时前
【C++ 面试高频:内存管理、RAII 和智能指针详解】
java·开发语言·word
凡人叶枫1 小时前
Effective C++ 条款39:明智而审慎地使用 private 继承
java·数据库·c++·嵌入式开发
轻刀快马2 小时前
跨越软硬件的共鸣(二):从 Cache 写策略看 Redis 与 DB 的一致性博弈
java·开发语言·redis·计算机组成原理
折哥的程序人生 · 物流技术专研2 小时前
Java 23 种设计模式:从踩坑到精通 | 装饰器模式 —— 比继承更灵活的扩展方式,你用过吗?
java·装饰器模式·java面试·结构型模式·java设计模式·javaio·从踩坑到精通
lili00122 小时前
2026 企业 AI 选型新范式:OpenRouter Fusion 证明多模型融合性价比远超单模型,企业该如何重构技术栈? - 微元算力(weytoken)
java·人工智能·python·重构·ai编程
shushangyun_2 小时前
汽车服务行业B2B平台+AI解决方案哪家专业:2026年最新测评
java·运维·网络·数据库·人工智能·汽车
A.说学逗唱的Coke2 小时前
【大模型专题】Spring AI Alibaba × Skill 整合实战:让 AI 真正“会干活
java·人工智能·spring
大黄说说2 小时前
深入理解 Go 协程 Goroutine:并发编程的核心精髓
java·数据库·python