C++设计模式之建造者模式详解
创作时间:
作者:
@小白创作中心
C++设计模式之建造者模式详解
引用
CSDN
1.
https://blog.csdn.net/JuicyActiveGilbert/article/details/146006545
建造者模式(Builder)是一种创建型设计模式,用于将复杂对象的构建过程分离,使得同样的构建步骤可以创建不同的表示形式。本文将详细介绍建造者模式的定义、结构、实现以及应用场景,并通过多个代码示例帮助读者更好地理解该模式。
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优化字符串等大型数据成员的传递效率
模式结构解析网图备份
本文原文来自CSDN
热门推荐
颈肩不适怎么办?6个简单习惯助您远离颈肩痛
君合的无限权益合伙人:法律探索与实务思考
音乐评论:2004年春晚歌曲《望月》的艺术魅力
MATLAB GUI设计教程:从入门到精通
甲辰年是哪一年及其计算方法解析 如何正确计算甲辰年及其意义是什么
总是莫名不开心,你不是情绪化,只是“情绪颗粒度”太低
GPT-4o数学能力跑分直掉50%,上海AI Lab开始给大模型重新出题了
狗狗骨折后的康复训练指南
狗狗急性肠胃炎,速就医!
《暗黑》第一季剧情深度解析:时间轮回与宿命的纠缠
梦见苹果的多重寓意:从文化象征到心理解析
天蓬元帅的职位解析:了解猪八戒在天庭的真正地位
手上长倒刺,千万别直接拔!有人因此拔甲治疗,提醒→
龙门臻德高级中学分享中考生如何给自己制定一套改进措施?
如何写一份简单明了的商业计划书(思维导图版本)
西蒙学习法:短时间内快速掌握新知识的秘诀,轻松成为学习高手
“无辣不欢”的人,好消息来了!爱吃辣的人糖尿病风险更低
为什么是700C?公路车轮径发展史
2024年丧葬抚恤金最新调整:退休人员离世后,家属能拿到多少抚恤金
镭铀钍的特性、用途及其在玉石领域的应用:全面解析与比较
割礼:文化、宗教与人权争议中的复杂传统与现代反思
指甲油美甲贴 健康使用指南
我国水下机器人的产业发展现状及趋势分析
望岳这首诗表达了诗人怎样的精神
ADR的定义和作用是什么?在投资中如何应用?
春天,西兰花和此是绝配,不放肉也很香,常给孩子做,一盘不够吃
如何蒸西兰花
如何用烤箱烤培根
云雾起,山朦胧!快来邂逅这些秋日云海
10万元级新能源汽车城市通勤指南:续航与充电全解析