🎯 导读:本文深入讲解工厂方法模式,带你告别简单工厂的”上帝类”噩梦,学会用”专厂专用”的方式优雅地创建对象!
🏭 工厂方法模式(Factory Method Pattern) 是我们之前讨论的”简单工厂模式”的究极进化版。
回想一下简单工厂的致命弱点:它严重违反了”开闭原则”(OCP) 🔒。如果工厂里要增加一种新产品,程序员就必须硬着头皮打开工厂类的源代码,在里面强行塞进一段 else if。当产品种类达到几十种时,那个工厂类就会变成一个难以维护的”上帝类” 👹。
工厂方法模式就是为了彻底消灭这个 if-else 噩梦 😈 而诞生的。
它的核心思想是:不再由一个万能的”总工厂”来生产所有东西,而是制定一个”工厂的标准契约” 📜,让每一种产品都拥有自己专属的”分工厂” 🏭。
📚 1. 客户端(使用者)需要知道哪些类?
在使用工厂方法模式时,作为写业务代码的客户端:
✅ 你需要知道 3 个类:
| 序号 | 类名 | 说明 |
|---|---|---|
| 1️⃣ | 抽象产品接口Abstract Product |
因为你要用它来接收对象并调用方法 |
| 2️⃣ | 抽象工厂接口Abstract Factory |
系统的核心骨架 🦴 |
| 3️⃣ | 具体工厂类Concrete Factory |
你需要实例化一个具体的工厂来为你干活 🏭 |
❌ 你不需要/绝不应该知道的类:
- 具体的产品类(Concrete Product): 客户端被完全隔离了!你拿到了具体的工厂,工厂产出什么就是什么,你根本不需要
include具体产品的头文件 🔒
🎬 2. 生动的实战场景:网格处理工作流的解析器
在构建结构优化底层的网格处理工作流时,系统需要解析不同格式的底层网格文件。最典型的比如 Gmsh 导出的 .msh 文件,以及包含了物理组等更丰富信息的 .med 文件。
❌ 如果用简单工厂
你会写一个 MeshParserFactory,里面写满:
1 | if (type == "msh") return new MshParser(); |
✅ 如果用工厂方法
我们在架构层面规定一个 “网格解析器工厂的接口 (IParserFactory)” 📜
| 文件格式 | 专属工厂 |
|---|---|
.msh |
MshFactory 🏭 |
.med |
MedFactory 🏭 |
.vtu (新增) |
VtuFactory 🏭 ➕ |
💡 要增加新格式?完全不动老代码,直接新建一个专属工厂即可!
📊 UML 类图
classDiagram
class IMeshParser {
<>
+parseFile(filePath)
}
class IParserFactory {
<>
+createParser()
}
class MshParser {
+parseFile(filePath)
}
class MedParser {
+parseFile(filePath)
}
class MshFactory {
+createParser()
}
class MedFactory {
+createParser()
}
IMeshParser <|-- MshParser : 实现
IMeshParser <|-- MedParser : 实现
IParserFactory <|-- MshFactory : 实现
IParserFactory <|-- MedParser : 实现
MshFactory ..> MshParser : 创建
MedFactory ..> MedParser : 创建
💻 3. C++ 现代代码生动演绎
让我们用现代 C++ 代码来看看这种设计到底有多优雅:
1 |
|
⚖️ 4. 工厂方法模式的优缺点
✅ 优点:
| 优点 | 说明 |
|---|---|
| 🔓 彻底遵守 OCP | 假设明天你需要引入 OpenCASCADE (OCC) 相关的边界解析,你只需要增加一个 OccParser 类和一个 OccFactory 类。原有代码一行都不用改! |
| 📐 遵守 SRP | 每个工厂只负责生产自己那一种特定的产品,逻辑极度纯粹 |
| 🔗 完美解耦 | 客户端代码(如上面的 executeWorkflow)被固定死了,不管未来的网格解析底层怎么翻天覆地,核心的控制流程永远不需要重构 |
❌ 缺点:
| 缺点 | 说明 |
|---|---|
| 💥 类爆炸 | 简单工厂只有一个工厂类,而工厂方法模式中,每增加一个产品,你就得成对地增加两个类(一个具体产品类 + 一个具体工厂类) |
| 😵 抽象复杂性 | 初级程序员看到满屏幕的 IThisFactory、IThatFactory 很容易头晕 |
🎯 总结:我该选”简单工厂”还是”工厂方法”?
🟢 用简单工厂,如果:
- 产品种类很少(2~3 种)
- 以后几乎绝对不会再增加了
- 想要代码看着清爽 ✨
🔵 用工厂方法模式,如果:
- 写一个会被很多人使用、不断迭代的底层框架库 🏗️
- 知道未来一定会源源不断地接入新的算法、新的文件格式、新的求解器
- 想要保你在未来几年不至于被改需求逼疯 🛡️
💡 一句话:简单工厂是”小而美”,工厂方法是”大而稳”!
- 本文作者: 迪丽惹Bug
- 本文链接: https://lyroom.github.io/2026/04/28/工厂方法模式详解/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!