工厂模式是创建型设计模式的核心成员,核心使命是 “封装对象的创建 / 获取逻辑,让客户端与具体对象的实现解耦” —— 简单说就是 “客户端不直接 new 对象,而是通过一个‘工厂’间接获取对象”。它的核心价值不是 “创建对象” 本身,而是 “隔离对象创建的复杂性”,让客户端只关心 “用什么”,不关心 “怎么造 / 怎么找”。
一、核心设计思想
工厂模式的本质是 “依赖抽象,不依赖具体”,通过三个关键组件实现解耦:
- 产品(Product) :被创建 / 获取的对象(可以是实体对象、解析器、适配器等),通常有统一的抽象接口(如
CGroupParser),保证客户端使用方式一致; - 工厂(Factory) :负责对象的创建 / 获取逻辑(如判断类型、初始化参数、适配环境),是模式的核心;
- 客户端(Client) :只依赖抽象产品和工厂接口,不直接操作具体产品的创建,实现 “无感知切换产品”。
核心目标:
- 降低耦合:客户端无需知道产品的具体实现;
- 简化维护:对象创建逻辑集中在工厂,修改时只需改工厂,无需改所有客户端;
- 支持扩展:新增产品时,只需扩展工厂,无需修改现有客户端代码(符合 “开放 - 封闭原则”)。
工厂模式的三大分类
工厂模式不是单一模式,而是一个 “家族”,按复杂度和适用场景分为三类,核心区别在于 “工厂的抽象程度” 和 “支持的产品范围”:
简单工厂(Simple Factory)
-
定义:一个工厂类(通常是工具类 / 静态类),根据输入参数(如类型、配置)直接返回对应的具体产品,无抽象工厂接口。
-
核心特点:
- 结构最简单:只有 “具体工厂”+“抽象产品 + 具体产品” 两层;
- 工厂是 “全能选手”:负责所有产品的创建逻辑,参数决定返回哪种产品;
- 缺点:扩展产品时需修改工厂类(违背开放 - 封闭原则),适合产品类型少、稳定的场景。
工厂方法(Factory Method)
-
定义:将简单工厂的 “全能逻辑” 拆分,为每个产品定义一个专属工厂(具体工厂),同时抽象出统一的工厂接口(抽象工厂)。客户端通过选择具体工厂,获取对应产品。
-
核心特点:
- 一个工厂只负责一个产品;
- 扩展灵活:新增产品时,只需新增 “具体产品 + 具体工厂”,无需修改现有代码;
- 缺点:产品增多时,工厂类会泛滥(如 4 种产品对应 4 个工厂),适合 “单一产品等级结构”。
-
核心对应关系:抽象工厂 → 具体工厂(N 个)→ 具体产品(N 个)(1:1 绑定)
抽象工厂(Abstract Factory)
-
定义:抽象工厂接口定义 “一个产品族下所有产品等级的创建方法”,每个具体工厂对应一个产品族,负责创建该族下所有产品。
-
核心特点:
- 聚焦 “产品族 + 产品等级” 双重区分:产品族、产品等级;
- 一个工厂负责一个产品族的所有产品;
- 优势:保证产品族内的一致性;
- 缺点:扩展产品等级需修改抽象工厂接口和所有具体工厂(耦合产品等级),适合 “产品等级结构稳定” 的场景。
-
核心对应关系:抽象工厂 → 具体工厂(N 个,对应 N 个产品族)→ 具体产品(N×M 个,对应 N 个产品族 × M 个产品等级)
三类工厂模式的对比表
| 维度 | 简单工厂 | 工厂方法 | 抽象工厂 |
|---|---|---|---|
| 核心定位 | 单一工厂 + 多产品 | 多工厂 + 多产品(1:1) | 多工厂 + 多产品族(1:N) |
| 抽象工厂接口 | 无 | 有(定义单一产品创建) | 有(定义产品族创建) |
| 扩展产品 | 修改工厂类(违背开放封闭) | 新增 “产品 + 工厂”(无修改) | 新增产品族:无修改;新增产品等级:需修改所有工厂 |
| 适用场景 | 产品少、稳定 | 单一产品等级、需灵活扩展 | 产品族 + 稳定产品等级、需保证族内一致性 |
| 复杂度 | 极低 | 中等 | 较高 |
| 典型场景 | 简单工具类创建(如日志器) | 单一类型产品扩展(如不同数据库连接) | 多类型组合产品(如版本 + 驱动、品牌 + 设备类型) |
工厂模式的适用场景与不适用场景
适用场景
- 对象创建逻辑复杂:如需要判断环境、初始化参数、适配依赖;
- 客户端需解耦具体实现,只关心动作,而不关注实现;
- 需支持产品扩展或切换;
- 需保证产品一致性:如抽象工厂保证 “产品族只返回族内相关产品”。
不适用场景
- 产品简单且稳定:如只需要创建一个固定参数的对象(直接
new更简洁); - 产品等级频繁变动:如频繁新增 / 删除产品等级,抽象工厂会陷入 “修改爆炸”;
- 无需解耦客户端与产品:如小型工具类,客户端直接操作产品无维护成本。
核心误区澄清
- 误区:工厂模式只能 “创建新对象”→ 纠正:工厂模式的核心是 “获取对象”,对象可以是新创建的、对现有资源的封装(如解析器)、从配置 / 缓存中获取的,甚至是适配器转换的;
- 误区:工厂模式越复杂越好→ 纠正:优先选择简单方案(如简单工厂、策略映射),只有需要 “产品族一致性” 或 “多产品等级组合” 时,才用抽象工厂;
- 误区:工厂模式必须用类继承→ 纠正:Go 语言中无需类继承,通过 “接口 + 结构体” 即可实现(如抽象工厂是接口,具体工厂是实现该接口的结构体)。
总结
工厂模式的核心是 “封装创建逻辑,解耦客户端与具体实现”,三类子模式分别对应不同复杂度的场景:
- 简单工厂:适合简单场景,追求简洁;
- 工厂方法:适合单一产品等级的灵活扩展;
- 抽象工厂:适合 “产品族 + 稳定产品等级” 的双重区分场景。
使用时的核心原则: “能简单不复杂” —— 如果不需要 “产品族” 或 “多产品等级”,优先用简单工厂或策略映射(非创建型方案),只有场景匹配时才用抽象工厂。