建造者模式:分步构建复杂对象

FreeGuideOnline 最新 2026-06-18

建造者模式:分步构建复杂对象

模式介绍

建造者模式(Builder Pattern)是一种创建型设计模式,用于分步骤创建复杂对象。它将对象的构造过程与表示分离,使相同的构建流程可以产生不同的产品形态。

当直接使用构造函数创建对象会变得臃肿、参数过多、可选参数逻辑混乱时,建造者模式提供了一种更加清晰、可读且易于维护的对象组装方案。该模式尤其适合参数组合爆炸对象内部结构精密度高的场景。

核心参与者

角色 职责
产品(Product) 最终构建出的复杂对象,包含多个部件。
抽象建造者(Builder) 定义构建产品各部件的抽象接口或协议。
具体建造者(ConcreteBuilder) 实现抽象建造者接口,组装具体部件并返回产品。
指挥者(Director) 规定构建步骤的顺序和流程,调用建造者的方法完成对象创建。

结构图解

         ┌──────────┐
         │  Director  │
         │ +construct│─────────────调用─────────────┐
         └──────────┘                              │
                                                  ▼
        ┌─────────────────────┐        ┌───────────────────────┐
        │     Builder         │        │    ConcreteBuilder     │
        │ +buildPartA()       │◄────── │ +buildPartA()          │
        │ +buildPartB()       │        │ +buildPartB()          │
        │ +getResult()        │        │ +getResult() -> Product│
        └─────────────────────┘        └───────────┬───────────┘
                                                  │ 创建
                                                  ▼
                                       ┌──────────────────┐
                                       │     Product      │
                                       │ +partA, +partB   │
                                       └──────────────────┘

代码实战:组装一台自定义电脑

下面用 Python 实现一个可配置电脑的建造者,展示经典版建造者与流式接口的混合用法。产品是一台 Computer,包含 CPU、内存、硬盘、显卡等部件。

1. 产品类

class Computer:
    def __init__(self):
        self.cpu = None
        self.ram = None
        self.storage = None
        self.gpu = None

    def __str__(self):
        return (f"Computer Specs:\n"
                f"CPU: {self.cpu}\n"
                f"RAM: {self.ram}\n"
                f"Storage: {self.storage}\n"
                f"GPU: {self.gpu}")

2. 抽象建造者与具体建造者

from abc import ABC, abstractmethod

class ComputerBuilder(ABC):
    @abstractmethod
    def set_cpu(self, cpu): pass

    @abstractmethod
    def set_ram(self, ram): pass

    @abstractmethod
    def set_storage(self, storage): pass

    @abstractmethod
    def set_gpu(self, gpu): pass

    @abstractmethod
    def get_result(self) -> Computer: pass

class GamingComputerBuilder(ComputerBuilder):
    def __init__(self):
        self.computer = Computer()

    def set_cpu(self, cpu):
        self.computer.cpu = cpu
        return self   # 支持链式调用

    def set_ram(self, ram):
        self.computer.ram = ram
        return self

    def set_storage(self, storage):
        self.computer.storage = storage
        return self

    def set_gpu(self, gpu):
        self.computer.gpu = gpu
        return self

    def get_result(self) -> Computer:
        return self.computer

3. 指挥者(可选,但集中控制步骤)

class Director:
    def __init__(self, builder: ComputerBuilder):
        self.builder = builder

    def build_gaming_pc(self):
        self.builder.set_cpu("Intel i9-13900K")
        self.builder.set_ram("32GB DDR5")
        self.builder.set_storage("2TB NVMe SSD")
        self.builder.set_gpu("NVIDIA RTX 4090")

    def build_office_pc(self):
        self.builder.set_cpu("Intel i5-13400")
        self.builder.set_ram("16GB DDR4")
        self.builder.set_storage("512GB SSD")
        self.builder.set_gpu("Integrated Graphics")

4. 客户端调用

# 使用指挥者
builder = GamingComputerBuilder()
director = Director(builder)
director.build_gaming_pc()
pc = builder.get_result()
print(pc)

# 直接链式调用(无需 Director)
office_pc = (GamingComputerBuilder()
             .set_cpu("AMD Ryzen 5 7600")
             .set_ram("16GB DDR5")
             .set_storage("1TB SSD")
             .set_gpu("Integrated")
             .get_result())
print(office_pc)

链式建造者:一种简化变体

在不需要 Director 的简单场景中,可以直接将构建步骤内聚到建造者内部,并通过返回 self 实现流式 API。这在配置类对象中非常流行。

class Burger:
    def __init__(self):
        self.bun = None
        self.patty = None
        self.cheese = False
        self.veggies = []

class BurgerBuilder:
    def __init__(self):
        self.burger = Burger()

    def with_bun(self, bun):
        self.burger.bun = bun
        return self

    def with_patty(self, patty):
        self.burger.patty = patty
        return self

    def add_cheese(self):
        self.burger.cheese = True
        return self

    def add_veggies(self, *veggies):
        self.burger.veggies.extend(veggies)
        return self

    def build(self):
        return self.burger

# 使用
burger = (BurgerBuilder()
          .with_bun("sesame")
          .with_patty("beef")
          .add_cheese()
          .add_veggies("lettuce", "tomato")
          .build())

进阶:多态建造者与不变式保护

在实际项目中,应当保护对象构建过程不被中断,避免创建出“半成品”对象。可以在 get_result()build() 中增加完整性校验,必要时抛出异常或返回可选值。

def get_result(self) -> Computer:
    if not self.computer.cpu or not self.computer.ram:
        raise ValueError("CPU and RAM are mandatory components")
    return self.computer

同时,可以为不同产品变体提供不同的建造者实现,利用多态让 Director 面向抽象接口编程,从而轻松切换家庭影院、游戏主机或办公笔记本的构建逻辑。

模式对比:建造者 vs 工厂 vs 抽象工厂

模式 关注点 使用时机
简单工厂/工厂方法 创建单个对象,隐藏实例化逻辑 对象创建简单,分支不多
抽象工厂 创建一系列相关对象族 需要保证产品族的一致性
建造者 逐步构造一个复杂对象 参数多、步骤复杂、要求不同表示

适用场景

  • 构造函数拥有大量参数,且多数可选,或参数之间存在依赖关系。
  • 需要创建不同表示的同一类对象(例如,不同配置的汽车、不同主题的文档)。
  • 对象的构建过程必须遵循特定顺序或步骤。
  • 希望将复杂对象的构建与使用分离,使代码更易维护。

优缺点一览

优点

  • 分步骤控制对象创建,代码清晰度大幅提升。
  • 隔离构建与表示,同样的流程可构建不同产品。
  • 符合开闭原则:新增具体建造者无需修改现有代码。
  • 支持链式调用,API 友好。

缺点

  • 会产生多个类,增加代码量。
  • 当产品间差异很小时可能显得冗余。
  • 若产品组成部分固定且简单,使用建造者反而过度设计。

小结

建造者模式通过将对象的构造逻辑封装在独立类中,使得复杂的组装过程变得透明且可控。它不仅是处理“构造函数魔鬼参数”的利器,更是实现流畅 DSL 风格代码的基础。合理运用指挥者与建造者的组合,能让系统同时获得灵活性与稳定性。

试着为你项目中的报表生成器、查询条件构建器或游戏角色装配系统引入建造者模式,你会立刻感受到它带来的秩序感。