什么是建造者模式?
建造者模式是一种创建型设计模式 ,它用于一步步地构建一个复杂对象,同时将对象的构建过程与它的表示分离开。简单来说:
- 它将复杂对象的"建造步骤"分成多部分,让我们可以灵活地控制这些步骤。
- 通过不同的建造者,构建过程可以生成不同的产品。
现实中的例子
想象你在快餐店点套餐:
- 每份套餐包括主食、饮料和甜品。
- 套餐1:汉堡 + 可乐 + 冰淇淋。
- 套餐2:三明治 + 果汁 + 蛋糕。
虽然套餐的结构相同,但具体的内容不同。如果你点套餐时,只需告诉服务员你要套餐1或套餐2,剩下的流程由服务员来完成。这种"组装"套餐的过程就是建造者模式的一个应用场景。
模式的特点
建造者模式特别适合构建那些:
- 由多个部分组成的复杂对象。
- 构建步骤固定但各部分内容可以变化。
- 需要创建不同类型的对象。
模式结构
建造者模式包含以下几个角色:
- 产品(Product) :
- 最终构建的复杂对象,由多个部分组成。
- 建造者(Builder) :
- 定义对象的构建步骤(如构建地基、搭建结构等)。
- 具体建造者(Concrete Builder) :
- 实现具体的构建逻辑,构建特定类型的产品。
- 指挥者(Director) :
- 控制建造过程,调用建造者的步骤按顺序完成构建。
- 客户端(Client) :
- 选择具体的建造者,通过指挥者完成产品构建,并获取最终产品。
用代码实现一个建造者模式
下面我们以建造房子为例,展示如何使用建造者模式来完成两种房子的构建:木屋 和 玻璃房。
1. 产品类(房子)
房子是一个复杂对象,由地基、结构和屋顶组成。
cpp
#include <iostream>
#include <string>
#include <memory> // 用于智能指针管理
// 产品类:房子
class House {
public:
void setFoundation(const std::string& foundation) {
foundation_ = foundation; // 设置地基
}
void setStructure(const std::string& structure) {
structure_ = structure; // 设置结构
}
void setRoof(const std::string& roof) {
roof_ = roof; // 设置屋顶
}
// 显示房子的组成部分
void show() const {
std::cout << "房子地基:" << foundation_
<< ",结构:" << structure_
<< ",屋顶:" << roof_ << "\n";
}
private:
std::string foundation_; // 地基
std::string structure_; // 结构
std::string roof_; // 屋顶
};
2. 抽象建造者(Builder)
定义房子的建造步骤,包括构建地基、搭建结构和安装屋顶。
cpp
// 抽象建造者类
class HouseBuilder {
public:
virtual ~HouseBuilder() = default;
virtual void buildFoundation() = 0; // 建造地基
virtual void buildStructure() = 0; // 建造结构
virtual void buildRoof() = 0; // 建造屋顶
virtual std::shared_ptr<House> getHouse() = 0; // 返回建造完成的房子
};
3. 具体建造者(木屋和玻璃房)
分别实现木屋和玻璃房的建造逻辑。
cpp
// 木屋建造者
class WoodenHouseBuilder : public HouseBuilder {
public:
WoodenHouseBuilder() {
house_ = std::make_shared<House>();
}
void buildFoundation() override {
house_->setFoundation("木制地基");
}
void buildStructure() override {
house_->setStructure("木制结构");
}
void buildRoof() override {
house_->setRoof("木制屋顶");
}
std::shared_ptr<House> getHouse() override {
return house_;
}
private:
std::shared_ptr<House> house_;
};
// 玻璃房建造者
class GlassHouseBuilder : public HouseBuilder {
public:
GlassHouseBuilder() {
house_ = std::make_shared<House>();
}
void buildFoundation() override {
house_->setFoundation("玻璃地基");
}
void buildStructure() override {
house_->setStructure("玻璃结构");
}
void buildRoof() override {
house_->setRoof("玻璃屋顶");
}
std::shared_ptr<House> getHouse() override {
return house_;
}
private:
std::shared_ptr<House> house_;
};
4. 指挥者类(Director)
指挥者定义房子的建造流程,并调用建造者完成房子。
cpp
// 指挥者类
class Director {
public:
void setBuilder(std::shared_ptr<HouseBuilder> builder) {
builder_ = builder;
}
// 建造房子的完整流程
void constructHouse() {
if (builder_) {
builder_->buildFoundation();
builder_->buildStructure();
builder_->buildRoof();
}
}
private:
std::shared_ptr<HouseBuilder> builder_;
};
5. 客户端代码
客户端选择建造的房子类型,通过指挥者控制建造流程,最后获取建好的房子。
cpp
int main() {
Director director; // 创建指挥者
// 构建木屋
auto woodenBuilder = std::make_shared<WoodenHouseBuilder>();
director.setBuilder(woodenBuilder);
director.constructHouse();
woodenBuilder->getHouse()->show(); // 输出木屋信息
// 构建玻璃房
auto glassBuilder = std::make_shared<GlassHouseBuilder>();
director.setBuilder(glassBuilder);
director.constructHouse();
glassBuilder->getHouse()->show(); // 输出玻璃房信息
return 0;
}
运行结果
程序运行后,输出如下:
房子地基:木制地基,结构:木制结构,屋顶:木制屋顶
房子地基:玻璃地基,结构:玻璃结构,屋顶:玻璃屋顶
模式的优缺点
优点:
- 分离复杂对象的创建过程与表示 :
- 客户端只需关心建造步骤,不必关心具体实现。
- 支持多种产品表示 :
- 可以通过不同的建造者创建不同的产品。
- 易于扩展 :
- 新增产品类型时,只需实现新的建造者类。
缺点:
- 增加复杂性 :
- 为每个产品类型都需要定义建造者,代码量可能较多。
- 不适合简单对象的构建 :
- 如果对象的结构简单,直接用工厂模式更高效。
适用场景
- 需要创建复杂对象:对象由多个部分组成,并且构建步骤固定。
- 希望支持不同的表示:同样的构建过程可以生成不同的产品(如木屋和玻璃房)。
总结
建造者模式通过将产品的建造过程分解为多个步骤,并定义好构建的流程,使得我们可以灵活地创建不同类型的复杂对象。
它在需要"分步骤创建复杂对象"且"支持多种表示"的场景中非常适用。
本文用构建房子的例子,详细展示了建造者模式的实现过程,希望你能理解并应用这一设计模式!
建造者模式完整程序及详细解释
以下是实现建造者模式的完整程序代码。我们以建造两种房子(木屋和玻璃房)为例,展示如何通过建造者模式分步骤创建复杂对象。
完整代码
cpp
#include <iostream>
#include <string>
#include <memory> // 用于智能指针管理
// 产品类:房子
class House {
public:
void setFoundation(const std::string& foundation) {
foundation_ = foundation; // 设置地基
}
void setStructure(const std::string& structure) {
structure_ = structure; // 设置结构
}
void setRoof(const std::string& roof) {
roof_ = roof; // 设置屋顶
}
// 显示房子的组成部分
void show() const {
std::cout << "房子地基:" << foundation_
<< ",结构:" << structure_
<< ",屋顶:" << roof_ << "\n";
}
private:
std::string foundation_; // 地基
std::string structure_; // 结构
std::string roof_; // 屋顶
};
// 抽象建造者类:定义房子建造的步骤
class HouseBuilder {
public:
virtual ~HouseBuilder() = default;
virtual void buildFoundation() = 0; // 建造地基
virtual void buildStructure() = 0; // 建造结构
virtual void buildRoof() = 0; // 建造屋顶
virtual std::shared_ptr<House> getHouse() = 0; // 返回建造完成的房子
};
// 木屋建造者:具体建造者
class WoodenHouseBuilder : public HouseBuilder {
public:
WoodenHouseBuilder() {
house_ = std::make_shared<House>();
}
void buildFoundation() override {
house_->setFoundation("木制地基");
}
void buildStructure() override {
house_->setStructure("木制结构");
}
void buildRoof() override {
house_->setRoof("木制屋顶");
}
std::shared_ptr<House> getHouse() override {
return house_;
}
private:
std::shared_ptr<House> house_;
};
// 玻璃房建造者:具体建造者
class GlassHouseBuilder : public HouseBuilder {
public:
GlassHouseBuilder() {
house_ = std::make_shared<House>();
}
void buildFoundation() override {
house_->setFoundation("玻璃地基");
}
void buildStructure() override {
house_->setStructure("玻璃结构");
}
void buildRoof() override {
house_->setRoof("玻璃屋顶");
}
std::shared_ptr<House> getHouse() override {
return house_;
}
private:
std::shared_ptr<House> house_;
};
// 指挥者类:负责控制建造流程
class Director {
public:
void setBuilder(std::shared_ptr<HouseBuilder> builder) {
builder_ = builder;
}
// 按照固定的步骤建造房子
void constructHouse() {
if (builder_) {
builder_->buildFoundation(); // 建造地基
builder_->buildStructure(); // 建造结构
builder_->buildRoof(); // 建造屋顶
}
}
private:
std::shared_ptr<HouseBuilder> builder_;
};
// 主函数:客户端代码
int main() {
Director director; // 创建指挥者
// 使用木屋建造者建造房子
auto woodenBuilder = std::make_shared<WoodenHouseBuilder>();
director.setBuilder(woodenBuilder);
director.constructHouse(); // 按步骤建造木屋
woodenBuilder->getHouse()->show(); // 显示木屋信息
// 使用玻璃房建造者建造房子
auto glassBuilder = std::make_shared<GlassHouseBuilder>();
director.setBuilder(glassBuilder);
director.constructHouse(); // 按步骤建造玻璃房
glassBuilder->getHouse()->show(); // 显示玻璃房信息
return 0;
}
运行结果
程序运行后,将输出如下内容:
房子地基:木制地基,结构:木制结构,屋顶:木制屋顶
房子地基:玻璃地基,结构:玻璃结构,屋顶:玻璃屋顶
本文由mdnice多平台发布