建造者模式和模板方法模式的区别
建造者模式 vs 模板方法模式 核心区别
一、一句话本质差异
- 模板方法模式(Template Method)
控制一套固定流程骨架,步骤顺序不能改,只允许重写内部单个步骤;侧重算法流程复用。 - 建造者模式(Builder)
拆分复杂对象的各个部件构造逻辑,部件组装顺序可灵活调整,最终统一产出完整对象;侧重复杂对象分步构建。
二、详细对比
1. 核心目标不同
模板方法
- 目标:复用算法流程
- 场景:一件事的执行步骤固定,只是每一步实现不同
- 例子:
饮料制作流程固定:烧水→加原料→冲泡→装杯;茶和咖啡只替换“加原料”步骤,顺序永远不变。
建造者
- 目标:分步组装复杂对象
- 场景:对象由多个独立部件组成,组装顺序可变、部件可替换,最终生成不同成品
- 例子:
组装电脑:CPU、主板、显卡、硬盘是独立部件;可以先装主板再装CPU,也能调换顺序;高配/低配电脑只是部件不同。
2. 流程控制权
模板方法
- 父类(抽象类)完全控制流程顺序
模板方法定义完整步骤顺序,子类只能实现步骤,不能修改执行先后。
// 父类固定流程publicfinalvoidmakeDrink(){boilWater();// 固定第一步addMaterial();// 子类实现brew();// 固定第三步pour();// 固定第四步}final模板方法防止子类篡改流程。
建造者
- Director指挥组装顺序,可灵活更换顺序;Builder只负责造单个零件
建造者只提供buildCPU()、buildGPU()等单个部件构建方法;导演类决定先装哪个,甚至可以两套组装逻辑。
// 导演控制组装顺序,可随意调换publicComputerconstructHighEnd(){builder.buildCPU();builder.buildGPU();builder.buildDisk();returnbuilder.getResult();}publicComputerconstructLowEnd(){builder.buildDisk();builder.buildCPU();// 不造显卡returnbuilder.getResult();}3. 产出物不同
- 模板方法:产出执行结果/行为(一段流程、一个动作),不一定是对象。
比如生成文档、制作饮品、游戏角色升级流程。 - 建造者:产出复杂复合对象(由多个子部件组合而成),一定是完整实体对象。
比如电脑、房屋、订单、复杂报文。
4. 结构组成对比
模板方法 组成
- 抽象父类:模板方法(固定流程)+ 抽象步骤
- 具体子类:实现抽象步骤
没有分离“构建”和“组装”,流程和步骤耦合在一个继承体系
建造者 组成
- 抽象Builder:定义所有部件构建接口
- 具体Builder:实现每个部件怎么造
- Director:专门控制组装顺序(可选)
- 产品Product:最终复杂对象
职责彻底拆分:造零件的类、组装顺序的类、成品类完全分离
5. 拓展方式(修改逻辑)
模板方法
只能新增子类重写步骤,流程骨架永远不变;不适合增减步骤。
如果需要新增流程步骤,必须修改父类模板方法,违反开闭原则。
建造者
- 新增部件:扩展Builder接口即可
- 更换组装顺序:新增Director构造方法,不用修改Builder
- 增减部件:组装时调用/不调用对应build方法即可,扩展性更强
三、最直观代码示例区分
示例1:模板方法(固定流程)
classDrinkTemplate:# 固定流程,顺序不可改defmake(self):self.boil_water()self.add_raw()self.brew()self.pour_cup()defboil_water(self):print("烧水")defbrew(self):print("浸泡")defpour_cup(self):print("倒入杯子")# 留给子类实现defadd_raw(self):passclassTea(DrinkTemplate):defadd_raw(self):print("加茶叶")classCoffee(DrinkTemplate):defadd_raw(self):print("加咖啡粉")# 使用:流程永远一样Tea().make()Coffee().make()示例2:建造者模式(组装对象,顺序可控)
# 产品:电脑classComputer:def__init__(self):self.cpu=""self.gpu=""# 建造者抽象classComputerBuilder:defbuild_cpu(self):passdefbuild_gpu(self):passdefget_pc(self):pass# 具体建造者classGamePCBuilder(ComputerBuilder):def__init__(self):self.pc=Computer()defbuild_cpu(self):self.pc.cpu="i9"defbuild_gpu(self):self.pc.gpu="4090"defget_pc(self):returnself.pc# 导演:控制组装顺序classDirector:defbuild_game_pc(self,builder):builder.build_cpu()builder.build_gpu()defbuild_simple_pc(self,builder):# 调换顺序、省略显卡builder.build_gpu()builder.build_cpu()# 使用builder=GamePCBuilder()dir=Director()dir.build_game_pc(builder)pc=builder.get_pc()四、一张总结表
| 对比维度 | 模板方法模式 | 建造者模式 |
|---|---|---|
| 核心关注点 | 固定算法流程,复用步骤骨架 | 拆分对象部件,灵活组装复杂实体 |
| 步骤顺序 | 父类固定,不可修改 | 由Director控制,可自由调换/删减 |
| 产出 | 一段行为/流程执行结果 | 多部件组合的复杂对象 |
| 类关系 | 依靠继承扩展步骤 | 依靠组合拆分构建与组装逻辑 |
| 职责拆分 | 流程和步骤都在同一继承树,耦合高 | 零件构建、组装顺序、成品完全分离 |
| 适用场景 | 步骤固定,仅内部实现有差异 | 对象结构复杂,部件多、组装可变 |
五、快速选型口诀
- 流程顺序固定,只是步骤实现不同 → 模板方法
- 要拼一个由多个零件组成的复杂对象,组装顺序可改 → 建造者
