前言
生成器是一种创建型设计模式,使你能够分步骤创建复杂对象。该模式允许你使用相同的创建代码生成不同类型和形式的对象。
问题
假设有这样一个复杂对象, 在对其进行构造时需要对诸多成员变量和嵌套对象进行繁复的初始化工作。 这些初始化代码通常深藏于一个包含众多参数且让人基本看不懂的构造函数中; 甚至还有更糟糕的情况, 那就是这些代码散落在客户端代码的多个位置。
例如, 我们来思考如何创建一个 房屋 House 对象。 建造一栋简单的房屋, 首先你需要建造四面墙和地板, 安装房门和一套窗户, 然后再建造一个屋顶。 但是如果你想要一栋更宽敞更明亮的房屋, 还要有院子和其他设施(例如暖气、 排水和供电设备), 那又该怎么办呢?
最简单的方法是扩展 房屋 基类, 然后创建一系列涵盖所有参数组合的子类。 但最终你将面对相当数量的子类。 任何新增的参数(例如门廊类型) 都会让这个层次结构更加复杂。
另一种方法则无需生成子类。 你可以在 房屋 基类中创建一个包括所有可能参数的超级构造函数, 并用它来控制房屋对象。 这种方法确实可以避免生成子类, 但它却会造成另外一个问题。
通常情况下, 绝大部分的参数都没有使用, 这使得对于构造函数的调用十分不简洁。 例如, 只有很少的房子有游泳池,因此与游泳池相关的参数十之八九是毫无用处的。
解决方案
生成器模式建议将对象构造代码从产品类中抽取出来, 并将其放在一个名为生成器的独立对象中。
该模式会将对象构造过程划分为一组步骤, 比如 buildWalls 创建墙壁 和 buildDoor 创建房门 等。 每次创建对象时, 你都需要通过生成器对象执行一系列步骤。 重点在于你无需调用所有步骤, 而只需调用创建特定对象配置所需的那些步骤即可。
当你需要创建不同形式的产品时, 其中的一些构造步骤可能需要不同的实现。 例如, 木屋的房门可能需要使用木头制造,而城堡的房门则必须使用石头制造。
在这种情况下, 你可以创建多个不同的生成器, 用不同方式实现一组相同的创建步骤。 然后你就可以在创建过程中使用这些生成器(例如按顺序调用多个构造步骤) 来生成不同类型的对象。
例如, 假设第一个建造者使用木头和玻璃制造房屋, 第二个建造者使用石头和钢铁, 而第三个建造者使用黄金和钻石。在调用同一组步骤后, 第一个建造者会给你一栋普通房屋,第二个会给你一座小城堡, 而第三个则会给你一座宫殿。 但是, 只有在调用构造步骤的客户端代码可以通过通用接口与建造者进行交互时, 这样的调用才能返回需要的房屋。
主管
你可以进一步将用于创建产品的一系列生成器步骤调用抽取成为单独的主管类。 主管类可定义创建步骤的执行顺序, 而生成器则提供这些步骤的实现。
严格来说, 你的程序中并不一定需要主管类。 客户端代码可直接以特定顺序调用创建步骤。 不过, 主管类中非常适合放入各种例行构造流程, 以便在程序中反复使用。
此外, 对于客户端代码来说, 主管类完全隐藏了产品构造细节。 客户端只需要将一个生成器与主管类关联, 然后使用主管类来构造产品, 就能从生成器处获得构造结果了。
结构

代码
#include
#include
#include
using namespace std;
enum Type{
simple, // 简单类型:墙 + 门
complex // 复杂类型:墙 + 门 + 屋顶
};
class Product{
public:
virtual void setWall() = 0;
virtual void setDoor() = 0;
virtual void setRoof() = 0;
// 打印产品信息的方法
virtual void showInfo() const {
cout "产品信息:" endl;
cout " 墙体: " m_wall endl;
cout " 门: " m_door endl;
cout " 屋顶: " (m_roof.empty() ? "无" : m_roof) endl;
cout "-------------------------" endl;
}
virtual ~Product(){}
protected:
string m_wall;
string m_door;
string m_roof;
};
class ModernProduct : public Product{
public:
void setWall() override { m_wall = "现代风格墙体"; }
void setDoor() override { m_door = "现代风格门"; }
void setRoof() override { m_roof = "现代风格屋顶"; }
// 重写showInfo以显示产品类型
void showInfo() const override {
cout "【现代风格产品】" endl;
Product::showInfo();
}
};
class OldProduct : public Product{
public:
void setWall() override { m_wall = "古典风格墙体"; }
void setDoor() override { m_door = "古典风格门"; }
void setRoof() override { m_roof = "古典风格屋顶"; }
// 重写showInfo以显示产品类型
void showInfo() const override {
cout "【古典风格产品】" endl;
Product::showInfo();
}
};
class Builder{
public:
virtual void reset() = 0;
virtual void buildWall() = 0;
virtual void buildDoor() = 0;
virtual void buildRoof() = 0;
virtual ~Builder(){}
};
class ModernBuilder : public Builder{
public:
void reset() override {
result = make_sharedModernProduct>();
}
void buildWall() override {
result->setWall();
}
void buildDoor() override {
result->setDoor();
}
void buildRoof() override {
result->setRoof();
}
shared_ptrModernProduct> getResult() {
return result;
}
private:
shared_ptrModernProduct> result;
};
class OldBuilder : public Builder{
public:
void reset() override {
result = make_sharedOldProduct>();
}
void buildWall() override {
result->setWall();
}
void buildDoor() override {
result->setDoor();
}
void buildRoof() override {
result->setRoof();
}
shared_ptrOldProduct> getResult() {
return result;
}
private:
shared_ptrOldProduct> result;
};
class Director{
public:
Director(shared_ptrBuilder> builder) : m_builder(builder) {}
void changeBuilder(shared_ptrBuilder> builder) {
m_builder = builder;
}
// 构建不同类型的产品
void make(Type type) {
// 每次构建前重置,确保是新的产品
m_builder->reset();
if (type == simple) {
cout "构建简单产品..." endl;
m_builder->buildWall();
m_builder->buildDoor();
}
else if (type == complex) {
cout "构建复杂产品..." endl;
m_builder->buildWall();
m_builder->buildDoor();
m_builder->buildRoof();
}
}
private:
shared_ptrBuilder> m_builder;
};
// 测试函数
void testBuilderPattern() {
// 创建现代风格构建器和指挥者
auto modernBuilder = make_sharedModernBuilder>();
auto director = make_sharedDirector>(modernBuilder);
// 构建现代风格复杂产品
director->make(complex);
auto modernProduct = modernBuilder->getResult();
modernProduct->showInfo();
// 构建现代风格简单产品
director->make(simple);
modernProduct = modernBuilder->getResult();
modernProduct->showInfo();
// 切换到古典风格构建器
auto oldBuilder = make_sharedOldBuilder>();
director->changeBuilder(oldBuilder);
// 构建古典风格复杂产品
director->make(complex);
auto oldProduct = oldBuilder->getResult();
oldProduct->showInfo();
// 构建古典风格简单产品
director->make(simple);
oldProduct = oldBuilder->getResult();
oldProduct->showInfo();
}
int main() {
cout "=== 生成器模式测试 ===" endl;
testBuilderPattern();
return 0;
}
文章来源于互联网:设计模式:生成器模式 Builder
你是否曾对自己的文章感到不满意,觉得表达不够精准,风格不够出彩? 你是否曾为修改文章而绞尽脑汁,却始终无法达到理想的效果? AI材料星的AI修改润色功能,将为你提供全方位的文章优化服务,它能够对文章进行多维度、多风格的修改和润色,让文章更加符合用户的需求,提升…
5bei.cn大模型教程网










