项目背景详细介绍

在复杂软件系统中,经常会遇到这样一类对象:

  • 构造参数非常多

  • 构造过程步骤复杂且有顺序要求

  • 同一类对象存在多种不同组合方式

  • 不同构造过程会产生“外观相同但内部配置不同”的对象

典型示例包括:

  • 复杂配置对象(如服务器配置、数据库配置)

  • UI 组件(窗口、对话框、表单)

  • 游戏角色或装备对象

  • 报文、协议数据包构造

如果直接通过一个“超长参数列表”的构造函数来创建对象,会带来以下问题:

  1. 构造函数可读性极差

  2. 调用方容易传错参数

  3. 构造过程与最终产品强耦合

  4. 难以扩展新的构造方式

为了解决“复杂对象的分步骤构建问题”,GoF 在《设计模式:可复用面向对象软件的基础》中提出了 建造者模式(Builder Pattern)

建造者模式的核心思想是:

将一个复杂对象的构建过程与其表示分离,使同样的构建过程可以创建不同的表示。

在 C++ 中,建造者模式非常适合用于解决“多步骤、可组合、可扩展”的对象构建问题。本项目将以完整教学级别,系统讲解 C++ 建造者模式的标准实现方案


项目需求详细介绍

本项目目标是实现一个 符合 GoF 定义、结构清晰、可直接用于生产的 C++ 建造者模式示例,具体需求如下。

功能性需求

  1. 支持分步骤构建复杂对象

  2. 支持不同建造过程生成不同产品

  3. 构建过程可复用

  4. 客户端无需关心具体构建细节

约束性需求

  1. 使用抽象建造者定义构建接口

  2. 使用具体建造者完成实际构建逻辑

  3. 使用指挥者(Director)控制构建顺序(经典实现)

  4. 所有源代码放在一个代码块中

  5. 不同文件使用注释区分

  6. 代码注释清晰,适合博客与课堂教学


相关技术详细介绍

1. 对象组合(Composition)

建造者模式通常通过对象组合的方式逐步组装产品对象,而不是在构造函数中一次性完成。


2. 抽象类与多态

通过抽象建造者类定义统一接口,使客户端与具体建造过程解耦。


3. 分步骤构建思想

将复杂对象的构建拆分为多个步骤(如 buildPartA、buildPartB),是建造者模式的核心。


实现思路详细介绍

本项目采用 GoF 经典建造者模式结构,整体设计如下:

  1. 定义产品类 Computer

  2. 定义抽象建造者 ComputerBuilder

  3. 定义具体建造者(如 GamingComputerBuilderOfficeComputerBuilder

  4. 定义指挥者 Director,负责控制构建流程

  5. 客户端通过 Director 获取最终产品

该结构的优势在于:

  • 构建步骤顺序可控

  • 构建过程可复用

  • 新增产品类型无需修改客户端代码


完整实现代码

说明:以下所有代码均放在一个代码块中,不同文件通过注释区分

/***************************************************
 * File: Computer.h
 ***************************************************/
#ifndef COMPUTER_H
#define COMPUTER_H

#include <string>
#include <iostream>

// 产品类:表示一个复杂对象
class Computer {
public:
    void setCPU(const std::string& cpu) { cpu_ = cpu; }
    void setGPU(const std::string& gpu) { gpu_ = gpu; }
    void setMemory(const std::string& memory) { memory_ = memory; }
    void setStorage(const std::string& storage) { storage_ = storage; }

    void show() const {
        std::cout << "CPU: " << cpu_ << std::endl;
        std::cout << "GPU: " << gpu_ << std::endl;
        std::cout << "Memory: " << memory_ << std::endl;
        std::cout << "Storage: " << storage_ << std::endl;
    }

private:
    std::string cpu_;
    std::string gpu_;
    std::string memory_;
    std::string storage_;
};

#endif // COMPUTER_H


/***************************************************
 * File: ComputerBuilder.h
 ***************************************************/
#ifndef COMPUTER_BUILDER_H
#define COMPUTER_BUILDER_H

#include "Computer.h"

// 抽象建造者
class ComputerBuilder {
public:
    virtual ~ComputerBuilder() {}

    virtual void buildCPU() = 0;
    virtual void buildGPU() = 0;
    virtual void buildMemory() = 0;
    virtual void buildStorage() = 0;

    virtual Computer* getResult() = 0;
};

#endif // COMPUTER_BUILDER_H


/***************************************************
 * File: GamingComputerBuilder.h
 ***************************************************/
#ifndef GAMING_COMPUTER_BUILDER_H
#define GAMING_COMPUTER_BUILDER_H

#include "ComputerBuilder.h"

// 具体建造者:游戏电脑
class GamingComputerBuilder : public ComputerBuilder {
public:
    GamingComputerBuilder() { computer_ = new Computer(); }

    ~GamingComputerBuilder() {
        // 构建完成后由客户端管理产品生命周期
    }

    void buildCPU() override {
        computer_->setCPU("Intel i9");
    }

    void buildGPU() override {
        computer_->setGPU("NVIDIA RTX 4090");
    }

    void buildMemory() override {
        computer_->setMemory("32GB DDR5");
    }

    void buildStorage() override {
        computer_->setStorage("2TB NVMe SSD");
    }

    Computer* getResult() override {
        return computer_;
    }

private:
    Computer* computer_;
};

#endif // GAMING_COMPUTER_BUILDER_H


/***************************************************
 * File: OfficeComputerBuilder.h
 ***************************************************/
#ifndef OFFICE_COMPUTER_BUILDER_H
#define OFFICE_COMPUTER_BUILDER_H

#include "ComputerBuilder.h"

// 具体建造者:办公电脑
class OfficeComputerBuilder : public ComputerBuilder {
public:
    OfficeComputerBuilder() { computer_ = new Computer(); }

    void buildCPU() override {
        computer_->setCPU("Intel i5");
    }

    void buildGPU() override {
        computer_->setGPU("Integrated Graphics");
    }

    void buildMemory() override {
        computer_->setMemory("16GB DDR4");
    }

    void buildStorage() override {
        computer_->setStorage("512GB SSD");
    }

    Computer* getResult() override {
        return computer_;
    }

private:
    Computer* computer_;
};

#endif // OFFICE_COMPUTER_BUILDER_H


/***************************************************
 * File: Director.h
 ***************************************************/
#ifndef DIRECTOR_H
#define DIRECTOR_H

#include "ComputerBuilder.h"

// 指挥者:控制构建顺序
class Director {
public:
    void setBuilder(ComputerBuilder* builder) {
        builder_ = builder;
    }

    Computer* construct() {
        builder_->buildCPU();
        builder_->buildGPU();
        builder_->buildMemory();
        builder_->buildStorage();
        return builder_->getResult();
    }

private:
    ComputerBuilder* builder_;
};

#endif // DIRECTOR_H


/***************************************************
 * File: main.cpp
 ***************************************************/
#include "Director.h"
#include "GamingComputerBuilder.h"
#include "OfficeComputerBuilder.h"

int main() {
    Director director;

    // 构建游戏电脑
    GamingComputerBuilder gamingBuilder;
    director.setBuilder(&gamingBuilder);
    Computer* gamingPC = director.construct();

    std::cout << "Gaming Computer Configuration:" << std::endl;
    gamingPC->show();

    std::cout << std::endl;

    // 构建办公电脑
    OfficeComputerBuilder officeBuilder;
    director.setBuilder(&officeBuilder);
    Computer* officePC = director.construct();

    std::cout << "Office Computer Configuration:" << std::endl;
    officePC->show();

    // 释放资源
    delete gamingPC;
    delete officePC;

    return 0;
}

代码详细解读

ComputerBuilder 接口

  • 定义构建复杂对象所需的所有步骤

  • 屏蔽具体产品实现细节


具体建造者类

  • 实现具体构建逻辑

  • 决定每个部件的具体实现


Director

  • 负责控制对象的构建顺序

  • 将构建算法与具体产品解耦


项目详细总结

通过本项目,我们实现了一个 标准、清晰、可扩展的 C++ 建造者模式,其主要优势包括:

  1. 有效解决复杂对象的构建问题

  2. 构建过程与产品表示彻底解耦

  3. 易于扩展新的产品类型

  4. 非常适合配置类、组合类对象


项目常见问题及解答

Q1:Director 是否必须?

不是必须的,但在复杂构建流程中非常有价值。

Q2:建造者模式和工厂模式的区别?

工厂关注“创建哪个对象”,建造者关注“如何一步步创建对象”。

Q3:能否使用链式调用?

可以,那属于建造者模式的变体实现。


扩展方向与性能优化

  1. 使用 std::unique_ptr 管理产品生命周期

  2. 去掉 Director,使用 Fluent Builder 风格

  3. 引入参数化构建步骤

  4. 与原型模式结合,复用构建结果

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐