重生之我在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. 需要注意异常处理,对于不支持的类型要给出合适的错误提示。

总结

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

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

相关推荐
jonyleek12 分钟前
数据可视化:JVS-BI仪表盘图表样式配置全攻略,打造个性化数据展示!
java·大数据·信息可视化·数据挖掘·数据分析·自动化·软件需求
WangMing_X13 分钟前
C# 单个函数实现各进制数间转换
java·开发语言·算法·c#·winform·软件
南宫生26 分钟前
贪心算法理论基础和习题【算法学习day.17】
java·学习·算法·leetcode·链表·贪心算法
jc0803kevin31 分钟前
solidity的struct对象,web3j java解析输出参数
java·web3·solidity
勇敢滴勇35 分钟前
【C++】继承和多态常见的面试问题
java·c++·面试
nice6666040 分钟前
初识JDBC
java·数据库·sql·mysql·idea
计算机学姐42 分钟前
基于SpringBoot的汽车票网上预订系统
java·vue.js·spring boot·后端·mysql·java-ee·mybatis
screamn1 小时前
Sentinel详解
java·sentinel
哎呦没1 小时前
农村扶贫管理:SpringBoot解决方案
java·spring boot·后端
只看见而已1 小时前
锁升级及线程池相关
java·开发语言