原型模式和工厂模式、建造者模式有什么区别?
简化版
原型模式通过复制已有对象创建新对象,工厂模式通过工厂封装对象创建逻辑,建造者模式通过分步骤组装复杂对象。原型关注“复制模板”,工厂关注“选择并创建产品”,建造者关注“按步骤构建复杂对象”。
详细版
三者都属于创建型模式,但创建思路不同:
| 模式 | 创建方式 | 关注点 | 典型场景 |
|---|---|---|---|
| 原型模式 | 复制已有对象 | 模板复用、对象复制 | 文档模板、游戏对象、图形复制 |
| 工厂模式 | 工厂创建对象 | 屏蔽具体类、选择产品 | 支付渠道、解析器、连接器 |
| 建造者模式 | 分步骤构建对象 | 复杂参数、构建过程清晰 | 配置对象、不可变对象、复杂 DTO |
如果已有一个标准模板,复制后微调,用原型模式;如果根据类型创建不同对象,用工厂模式;如果对象参数多、构建步骤复杂,用建造者模式。
完整版教学
一、原型模式:从已有对象复制
原型模式的创建入口是已有对象:
Document doc = template.copy();
它适合已有模板,且新对象大部分字段和模板相同的场景。
例如合同模板、图形元素、游戏怪物模板,都可以复制后修改少量字段。
二、工厂模式:由工厂决定创建哪类对象
工厂模式通常是:
Payment payment = paymentFactory.create("wechat");
客户端不关心具体类是 WechatPayment 还是 AliPayment。
工厂模式重点是隐藏对象创建逻辑和具体类型选择。
它不一定依赖已有对象模板。
三、建造者模式:分步骤组装复杂对象
建造者模式通常是:
OrderQuery query = OrderQuery.builder()
.userId(1001L)
.status("PAID")
.startTime(start)
.endTime(end)
.build();
它适合参数多、可选字段多、构建过程需要校验的对象。
建造者关注的是构造过程清晰,而不是复制已有对象。
四、从问题特征判断用哪个
可以这样判断:
- 有模板,复制后改一点:原型模式;
- 有多个产品类型,需要按条件创建:工厂模式;
- 参数很多,构造过程复杂:建造者模式。
例如报表系统:
- 从“销售日报模板”复制一份:原型;
- 根据格式创建 PDF/Excel 导出器:工厂;
- 组装复杂查询条件:建造者。
五、三者可以组合使用
真实项目里三者并不冲突。
比如低代码平台:
- 工厂根据组件类型找到组件创建器;
- 注册表保存组件原型;
- 复制原型得到组件实例;
- 建造者组装组件的复杂配置。
模式之间可以配合,只要每一层目的清楚。
六、常见误区与追问
三种创建型模式的输入不同:原型从1个现成对象复制,工厂从类型或配置选择产品,建造者从多个步骤收集参数后组装。创建一台预配置服务器时,工厂可选 Linux 产品族,Builder 设置 CPU/内存,最后原型复制标准镜像;它们并非互斥替代。
| 检查维度 | 判定依据 |
|---|---|
| 原型 | 复用现成实例状态 |
| 工厂 / 建造者 | 选择产品 / 分步组装 |
记忆钩子:原型从“成品”出发,工厂从“品类”出发,建造者从“零件步骤”出发。
- 误区:三者只能选择一个。 工厂可以管理原型,Builder 也可先复制模板再覆盖部分参数。
- 追问:参数很多就一定用 Builder 吗? 还要看是否存在分步校验和可读构建需求,普通参数对象可能足够。
- 误区:原型不需要构造过程。 原型自身仍要被首次创建和初始化,只是后续复用该状态。
- 追问:运行期新增模板更适合哪个? 原型配合注册表可动态登记实例,而工厂通常围绕已知产品类型。
- 追问:面试中如何快速选择? 看需求强调复制已有状态、隐藏具体类型,还是控制复杂组装步骤。
七、加强记忆
原型、工厂、建造者都解决对象创建问题,但切入点不同。原型靠复制模板,工厂靠封装选择和创建,建造者靠分步骤组装。看到“模板复制”选原型,看到“按类型创建”选工厂,看到“参数复杂”选建造者。