建造者模式的核心价值在于解耦复杂对象的构建过程与表示,从而提高代码灵活性和可维护性。1. 它通过将构建步骤封装到具体建造者中,实现对构建过程的细粒度控制;2. 允许使用相同的构建流程创建不同表示的产品,如跑车和城市车;3. 避免构造函数参数爆炸问题,提升可读性和健壮性;4. 支持不可变对象的设计,确保对象一旦创建状态即固定;5. 适用于对象构造复杂多变、需要分步进行、希望避免构造函数臃肿及需创建多种产品变体的场景。

在C++中,建造者模式(Builder Pattern)的核心在于将一个复杂对象的构建过程与其表示分离,这样通过相同的构建过程可以创建不同的表示。它允许你分步构建一个复杂对象,而不是在构造函数中一次性完成所有操作,这对于那些拥有大量可选参数或构建步骤复杂的对象来说,简直是救星。

建造者模式通常涉及几个关键角色:产品(Product)、抽象建造者(Builder)、具体建造者(ConcreteBuilder)和指挥者(Director)。

我们以构建一辆“汽车”为例。一辆汽车可以有不同的发动机、车轮和颜色。
立即学习“C++免费学习笔记(深入)”;
#include <iostream>
#include <string>
#include <vector>
#include <memory> // For std::unique_ptr
// 1. 产品 (Product)
// 这是我们要构建的复杂对象
class Car {
public:
void addPart(const std::string& part) {
parts_.push_back(part);
}
void show() const {
std::cout << "Car Parts:" << std::endl;
for (const auto& part : parts_) {
std::cout << "- " << part << std::endl;
}
}
private:
std::vector<std::string> parts_;
};
// 2. 抽象建造者 (Builder)
// 定义创建产品各个部件的接口
class CarBuilder {
public:
virtual ~CarBuilder() = default;
virtual void buildEngine() = 0;
virtual void buildWheels() = 0;
virtual void buildColor() = 0;
virtual std::unique_ptr<Car> getResult() = 0;
};
// 3. 具体建造者 (ConcreteBuilder)
// 实现抽象建造者接口,构建和装配产品的各个部件
class SportsCarBuilder : public CarBuilder {
public:
SportsCarBuilder() : car_(std::make_unique<Car>()) {}
void buildEngine() override {
car_->addPart("Powerful V8 Engine");
}
void buildWheels() override {
car_->addPart("Sport Alloy Wheels");
}
void buildColor() override {
car_->addPart("Racing Red Color");
}
std::unique_ptr<Car> getResult() override {
return std::move(car_); // 转移所有权
}
private:
std::unique_ptr<Car> car_;
};
class CityCarBuilder : public CarBuilder {
public:
CityCarBuilder() : car_(std::make_unique<Car>()) {}
void buildEngine() override {
car_->addPart("Economical 4-Cylinder Engine");
}
void buildWheels() override {
car_->addPart("Standard Steel Wheels");
}
void buildColor() override {
car_->addPart("Urban Gray Color");
}
std::unique_ptr<Car> getResult() override {
return std::move(car_);
}
private:
std::unique_ptr<Car> car_;
};
// 4. 指挥者 (Director)
// 负责安排构建过程,它知道如何使用建造者接口来构建产品
class CarDirector {
public:
void setBuilder(CarBuilder* builder) {
builder_ = builder;
}
// 构造一个完整的汽车
void construct() {
if (builder_) {
builder_->buildEngine();
builder_->buildWheels();
builder_->buildColor();
}
}
private:
CarBuilder* builder_ = nullptr; // 不拥有所有权
};
// 客户端代码示例
/*
int main() {
CarDirector director;
SportsCarBuilder sportsBuilder;
director.setBuilder(&sportsBuilder);
director.construct();
std::unique_ptr<Car> sportsCar = sportsBuilder.getResult();
std::cout << "--- Sports Car ---" << std::endl;
sportsCar->show();
std::cout << std::endl;
CityCarBuilder cityBuilder;
director.setBuilder(&cityBuilder);
director.construct();
std::unique_ptr<Car> cityCar = cityBuilder.getResult();
std::cout << "--- City Car ---" << std::endl;
cityCar->show();
return 0;
}
*/这段代码展示了如何通过不同的
ConcreteBuilder
SportsCarBuilder
CityCarBuilder
Director
Car
Director
Builder
ConcreteBuilder
Director
Car

说实话,刚开始接触建造者模式的时候,我常常会觉得它有点“大材小用”,特别是对于那些参数不多的简单对象。但当你的对象开始变得复杂,拥有十几个甚至几十个可选参数,或者构建过程本身就涉及多个步骤、条件判断时,建造者模式的价值就凸显出来了。
它的核心价值在于:
Car
CarBuilder
buildXxx
bool
true, false, true, false
对我个人而言,它更像是一种“有序组装”的思维方式。你不是一次性把所有零件扔进一个黑箱子,而是有条不紊地、一步步地完成组装,每一步都清晰可见。
选择一个设计模式,从来不是因为它“酷”或者“流行”,而是因为它能解决你当前面临的实际问题。建造者模式也不例外。以下是我在实践中总结的一些判断点:
getResult()
它和工厂模式的区别也值得一提。工厂模式主要是解决“创建什么”的问题,它返回的是一个特定类型的对象实例。而建造者模式解决的是“如何创建”的问题,它关注的是复杂对象的构建过程,以及如何通过这个过程来生成不同表示的对象。它们关注点不同,但有时也会配合使用。
任何设计模式都有它的双刃剑效应,建造者模式也不例外。我在实际项目中也踩过一些坑,或者看到别人滥用它导致代码变得更复杂。
Builder
ConcreteBuilder
Director
Director
Builder
Director
Director
Builder
Builder
Builder
std::unique_ptr
std::shared_ptr
Director
CarBuilder* builder_
Director
builder_
我的经验是,在决定使用建造者模式之前,先问自己几个问题:这个对象真的足够复杂吗?它的构建过程真的需要分步吗?将来会有很多不同“风味”的产品出现吗?如果答案是肯定的,那么建造者模式会是你的好帮手;否则,也许更简单的方案才是最佳选择。不要为了用模式而用模式。
以上就是建造者模式在C++怎么实现 分步构建复杂对象的技巧的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号