重生之我在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();
}
}
}
这段代码存在几个明显的问题:
- 每次添加新的文档类型都需要修改这个方法
- 对象创建的逻辑和业务逻辑混在一起
- 违反了开闭原则,对修改开放,对扩展关闭
简单工厂模式:第一步改进
让我们用简单工厂模式来改进这段代码。首先,我们定义一个文档处理的接口:
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");
}
}
}
工厂模式的优势
通过上面的示例,我们可以看到工厂模式带来的几个明显优势:
解耦性:对象的创建与使用分离,客户端代码不需要知道具体类的创建细节。
可维护性:所有对象创建的逻辑都集中在一处,便于统一管理和修改。
可扩展性:添加新的类型时,只需要修改工厂类,不需要修改现有的业务代码。
注意事项
虽然简单工厂模式使用方便,但也要注意以下几点:
-
工厂类的职责相对较重,包含了所有对象的创建逻辑,在类型非常多的情况下可能需要考虑拆分。
-
添加新产品时仍然需要修改工厂类的代码,这一点上违反了开闭原则。在产品类型经常变动的场景下,可能需要考虑使用工厂方法模式或抽象工厂模式。
-
需要注意异常处理,对于不支持的类型要给出合适的错误提示。
总结
简单工厂模式是一种应用广泛的设计模式,它通过将对象创建的逻辑封装在工厂类中,实现了对象创建和使用的解耦。在实际开发中,简单工厂模式常常是重构的第一步,它为后续可能的扩展打下了良好的基础。
虽然简单工厂模式可能违反开闭原则,但在变化相对较小的系统中,它的简单性和实用性使它成为了一个很好的选择。在实际应用中,我们需要根据具体场景来权衡是否使用简单工厂模式,或是选择更复杂的工厂方法模式、抽象工厂模式。