当前位置: 首页 > news >正文

【C++设计模式】第四篇:建造者模式(Builder)

注意:复现代码时,确保 VS2022 使用 C++17/20 标准以支持现代特性。

分步骤构造复杂对象,实现灵活装配


1. 模式定义与用途

核心目标:将复杂对象的构建过程分离,使得同样的构建步骤可以创建不同的表示形式。
常见场景

  • 创建包含多个组件的复杂对象(如游戏角色、文档格式)
  • 需要逐步构造对象,并支持不同配置选项
  • 避免构造函数参数爆炸(尤其是可选参数众多时)

2. 模式结构解析

在这里插入图片描述

  • Builder:定义构造步骤的抽象接口(如 buildHead(), buildBody()
  • ConcreteBuilder:实现具体构造逻辑,提供获取结果的接口
  • Director:控制构造流程(可选,可让客户端直接操作Builder)
  • Product:最终构造的复杂对象

3. 现代 C++ 实现示例:游戏角色构造

3.1 基础实现

#include <iostream>
#include <memory>
#include <string>

// 产品:游戏角色
class GameCharacter {
public:
    void setHead(const std::string& head) { head_ = head; }
    void setBody(const std::string& body) { body_ = body; }
    void setWeapon(const std::string& weapon) { weapon_ = weapon; }

    void describe() const {
        std::cout << "Character: " << head_ << ", " << body_ 
                  << ", wielding " << weapon_ << "\n";
    }

private:
    std::string head_;
    std::string body_;
    std::string weapon_;
};

// 抽象建造者
class CharacterBuilder {
public:
    virtual ~CharacterBuilder() = default;
    virtual void buildHead() = 0;
    virtual void buildBody() = 0;
    virtual void buildWeapon() = 0;
    virtual std::unique_ptr<GameCharacter> getResult() = 0;
};

// 具体建造者:骑士
class KnightBuilder : public CharacterBuilder {
public:
    KnightBuilder() { character_ = std::make_unique<GameCharacter>(); }

    void buildHead() override { character_->setHead("Steel Helmet"); }
    void buildBody() override { character_->setBody("Plate Armor"); }
    void buildWeapon() override { character_->setWeapon("Longsword"); }
    std::unique_ptr<GameCharacter> getResult() override { return std::move(character_); }

private:
    std::unique_ptr<GameCharacter> character_;
};

// 具体建造者:法师
class MageBuilder : public CharacterBuilder {
public:
    MageBuilder() { character_ = std::make_unique<GameCharacter>(); }

    void buildHead() override { character_->setHead("Pointed Hat"); }
    void buildBody() override { character_->setBody("Robe"); }
    void buildWeapon() override { character_->setWeapon("Staff"); }
    std::unique_ptr<GameCharacter> getResult() override { return std::move(character_); }

private:
    std::unique_ptr<GameCharacter> character_;
};

// 指挥者(可选)
class CharacterDirector {
public:
    std::unique_ptr<GameCharacter> createCharacter(CharacterBuilder& builder) {
        builder.buildHead();
        builder.buildBody();
        builder.buildWeapon();
        return builder.getResult();
    }
};

// 客户端代码
int main() {
    KnightBuilder knightBuilder;
    MageBuilder mageBuilder;
    CharacterDirector director;

    auto knight = director.createCharacter(knightBuilder);
    auto mage = director.createCharacter(mageBuilder);

    knight->describe(); // Character: Steel Helmet, Plate Armor, wielding Longsword
    mage->describe();   // Character: Pointed Hat, Robe, wielding Staff

    return 0;
}

代码解析:

  • 将角色构造分解为独立步骤,新增角色类型只需添加新的 ConcreteBuilder
  • 使用 std::unique_ptr 明确所有权转移,防止资源泄漏

3.2 支持链式调用的增强实现

// 流畅接口(Fluent Interface)改进
class AdvancedCharacterBuilder {
public:
    AdvancedCharacterBuilder& withHead(const std::string& head) {
        head_ = head;
        return *this;
    }

    AdvancedCharacterBuilder& withBody(const std::string& body) {
        body_ = body;
        return *this;
    }

    AdvancedCharacterBuilder& withWeapon(const std::string& weapon) {
        weapon_ = weapon;
        return *this;
    }

    std::unique_ptr<GameCharacter> build() {
        auto character = std::make_unique<GameCharacter>();
        character->setHead(head_);
        character->setBody(body_);
        character->setWeapon(weapon_);
        return character;
    }

private:
    std::string head_;
    std::string body_;
    std::string weapon_;
};

// 客户端使用
void createCustomCharacter() {
    auto builder = AdvancedCharacterBuilder();
    auto character = builder.withHead("Hood")
                             .withBody("Leather Armor")
                             .withWeapon("Dagger")
                             .build();
    character->describe();
}

代码解析

  • 通过返回 this 指针实现链式调用,提升代码可读性
  • 支持可选参数和任意顺序设置属性

4. 应用场景示例:HTTP请求构造

class HttpRequest {
public:
    void setMethod(const std::string& method) { method_ = method; }
    void setUrl(const std::string& url) { url_ = url; }
    void addHeader(const std::string& key, const std::string& value) {
        headers_[key] = value;
    }
    void setBody(const std::string& body) { body_ = body; }

    void send() const {
        std::cout << "Sending " << method_ << " " << url_ 
                  << " with body: " << body_ << "\n";
    }

private:
    std::string method_;
    std::string url_;
    std::map<std::string, std::string> headers_;
    std::string body_;
};

class HttpRequestBuilder {
public:
    HttpRequestBuilder() : request_(std::make_unique<HttpRequest>()) {}

    HttpRequestBuilder& method(const std::string& method) {
        request_->setMethod(method);
        return *this;
    }

    HttpRequestBuilder& url(const std::string& url) {
        request_->setUrl(url);
        return *this;
    }

    HttpRequestBuilder& header(const std::string& key, const std::string& value) {
        request_->addHeader(key, value);
        return *this;
    }

    HttpRequestBuilder& body(const std::string& body) {
        request_->setBody(body);
        return *this;
    }

    std::unique_ptr<HttpRequest> build() {
        return std::move(request_);
    }

private:
    std::unique_ptr<HttpRequest> request_;
};

// 使用示例
void sendPostRequest() {
    auto request = HttpRequestBuilder()
        .method("POST")
        .url("https://api.example.com/data")
        .header("Content-Type", "application/json")
        .body(R"({"key": "value"})")
        .build();
    request->send();
}

5. 优缺点分析

优点缺点
分步骤构造复杂对象,代码清晰需定义多个Builder类,增加代码量
支持不同配置和构造顺序对简单对象可能过度设计
隔离复杂构造逻辑与业务代码需维护Builder与Product的同步

6. 调试与优化策略

  • 参数验证:在Builder方法中添加有效性检查,防止非法状态
  • 对象复用:对频繁创建的对象,实现reset()方法重用Builder实例
  • 性能分析:使用std::move优化字符串等大型数据成员的传递效率

模式结构解析网图备份

在这里插入图片描述

相关文章:

  • Android14 串口控制是能wifi adb实现简介
  • SQLAlchemy系列教程:理解SQLAlchemy元数据
  • 【AI深度学习基础】NumPy完全指南终极篇:核心功能与工程实践(含完整代码)
  • 论文阅读和代码实现EfficientDet(BiFPN)
  • 探索 Hutool - JSON:高效的 JSON 处理利器
  • DeepSeek:全栈开发者视角下的AI革命者
  • 【2025rust笔记】超详细,小白,rust基本语法
  • 数据结构第五节:排序
  • 知识图谱+智能问诊预诊系统vue+django+neo4j架构、带问诊历史
  • 在 Linux 系统上安装部署 Docker
  • 高频 SQL 50 题(基础版)_1084. 销售分析 III
  • mapbox基础,使用点类型geojson加载symbol符号图层,用于标注文字
  • Python 网络爬虫教程与案例详解
  • Linux跳过密码登录MySQL,实现重置mysql密码,导入导出数据库
  • Python实现一个类似MybatisPlus的简易SQL注解
  • 新装的conda 以及pycharm未能正确初始化,或conda环境变量配置错误问题解决!!!
  • 若依框架中的岗位与角色详解
  • Stable Diffusion模型Pony系列模型深度解析
  • 在Linux中开发OpenGL——环境搭建
  • 在 Windows 和 Linux 系统上安装和部署 Ollama
  • 包头网站建设 奥北/会员制营销
  • 南通南通网站优化/郑州关键词优化费用
  • 南阳做网站的公/惠州seo外包费用
  • 泉州网站开发建设/软文发布平台哪个好
  • 苏州网站建设点一点/百度一下百度主页
  • 青岛网站建设设计/最近的新闻大事10条