文章目录
一、建造者模式的基本概念
建造者模式(亦称:生成器模式)是一种创建型设计模式, 使你能够分步骤创建复杂对象。 该模式允许你使用相同的创建代码生成不同类型和形式的对象。 将一个复杂对象的构建过程与它的表示 分离,使得同样的构建过程可以创建不同的表示。
- 意图:处理复杂对象的创建问题,尤其是需要分步骤组装的对象。
- 核心思想:把复杂对象的创建过程抽象出来,使用不同的"建造者"来构造不同的表示。
使用场景:
- 对象构建复杂:对象有很多组成部分,且构建步骤固定,但具体实现不同。
- 同样的构建过程,不同的表示:比如:
- 游戏中创建不同风格的角色(武士、法师)。
- 生成不同格式的报表(PDF、HTML、Excel)。
- 组装汽车(跑车、越野车)。
总结:
- 建造者模式更适合"复杂对象的分步骤组装"。
- 相比工厂模式,建造者模式更关注"组装过程"。
二、建造者模式结构
角色组成:
- Product(产品类):最终要创建的复杂对象;由多个部件组成。
- Builder(抽象建造者):规定创建产品的抽象步骤(通常有 buildPartA()、buildPartB() 等)。不涉及具体部件的实现。
- ConcreteBuilder(具体建造者):实现 Builder 的接口,具体完成产品部件的创建。最终返回一个完整的 Product。
- Director(指挥者):调用建造者的步骤方法,控制构建过程。不关心具体的产品细节,只负责组装。
UML类图:
说明:
- Product(抽象产品):定义了产品的公共接口。
- ConcreteProductA / ConcreteProductB(具体产品):实现 Product 接口,不同的产品有不同的行为。
- Factory(工厂类):提供一个静态方法 createProduct(type),根据参数决定创建哪一种 Product 实例。
三、示例代码
3.1基本示例
cpp
#include <iostream>
#include <string>
using namespace std;
// 产品类
class Product {
public:
void setPartA(const string& part) { partA = part; }
void setPartB(const string& part) { partB = part; }
void show() {
cout << "Product parts: " << partA << ", " << partB << endl;
}
private:
string partA;
string partB;
};
// 抽象建造者
class Builder {
public:
virtual ~Builder() {}
virtual void buildPartA() = 0;
virtual void buildPartB() = 0;
virtual Product* getResult() = 0;
};
// 具体建造者
class ConcreteBuilder : public Builder {
public:
ConcreteBuilder() { product = new Product(); }
void buildPartA() override { product->setPartA("Part A"); }
void buildPartB() override { product->setPartB("Part B"); }
Product* getResult() override { return product; }
private:
Product* product;
};
// 指挥者
class Director {
public:
Director(Builder* b) : builder(b) {}
Product* construct() {
builder->buildPartA();
builder->buildPartB();
return builder->getResult();
}
private:
Builder* builder;
};
// 使用示例
int main() {
Builder* builder = new ConcreteBuilder();
Director director(builder);
Product* product = director.construct();
product->show();
delete product;
delete builder;
return 0;
}
3.2 构建一个复杂的 QWidget 界面(包含标题、按钮、输入框等)
需求场景:
- 我们要创建一个 不同风格的界面(比如 登录界面、注册界面)。
- 构建过程是固定的:添加标题 → 添加输入框 → 添加按钮。
- 使用建造者模式来灵活组装。
示例代码:
cpp
#include <QApplication>
#include <QWidget>
#include <QVBoxLayout>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
// ================= Product =================
class ComplexWidget : public QWidget {
public:
ComplexWidget(QWidget *parent = nullptr) : QWidget(parent) {
layout = new QVBoxLayout(this);
setLayout(layout);
}
void addTitle(const QString &text) {
QLabel *label = new QLabel(text, this);
label->setAlignment(Qt::AlignCenter);
layout->addWidget(label);
}
void addInput(const QString &placeholder) {
QLineEdit *edit = new QLineEdit(this);
edit->setPlaceholderText(placeholder);
layout->addWidget(edit);
}
void addButton(const QString &text) {
QPushButton *btn = new QPushButton(text, this);
layout->addWidget(btn);
}
private:
QVBoxLayout *layout;
};
// ================= Builder =================
class Builder {
public:
virtual ~Builder() {}
virtual void buildTitle() = 0;
virtual void buildInputs() = 0;
virtual void buildButtons() = 0;
virtual ComplexWidget* getResult() = 0;
};
// ================= ConcreteBuilder: 登录界面 =================
class LoginBuilder : public Builder {
public:
LoginBuilder() { widget = new ComplexWidget(); }
void buildTitle() override {
widget->addTitle("用户登录");
}
void buildInputs() override {
widget->addInput("用户名");
widget->addInput("密码");
}
void buildButtons() override {
widget->addButton("登录");
widget->addButton("取消");
}
ComplexWidget* getResult() override { return widget; }
private:
ComplexWidget *widget;
};
// ================= ConcreteBuilder: 注册界面 =================
class RegisterBuilder : public Builder {
public:
RegisterBuilder() { widget = new ComplexWidget(); }
void buildTitle() override {
widget->addTitle("用户注册");
}
void buildInputs() override {
widget->addInput("用户名");
widget->addInput("邮箱");
widget->addInput("密码");
widget->addInput("确认密码");
}
void buildButtons() override {
widget->addButton("注册");
widget->addButton("返回");
}
ComplexWidget* getResult() override { return widget; }
private:
ComplexWidget *widget;
};
// ================= Director =================
class Director {
public:
Director(Builder *b) : builder(b) {}
ComplexWidget* construct() {
builder->buildTitle();
builder->buildInputs();
builder->buildButtons();
return builder->getResult();
}
private:
Builder *builder;
};
// ================= main =================
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
// 选择不同的 Builder
Builder *builder = nullptr;
// 登录界面
builder = new LoginBuilder();
Director directorLogin(builder);
ComplexWidget *loginWidget = directorLogin.construct();
loginWidget->setWindowTitle("建造者模式 - 登录界面");
loginWidget->show();
delete builder;
// 注册界面
builder = new RegisterBuilder();
Director directorRegister(builder);
ComplexWidget *registerWidget = directorRegister.construct();
registerWidget->setWindowTitle("建造者模式 - 注册界面");
registerWidget->move(400, 100);
registerWidget->show();
delete builder;
return app.exec();
}
3.2.日常类比示例
示例场景:
- 一辆汽车由发动机、车轮、车身 三部分组成。
- 我们可以用同样的构建步骤,来造不同类型的车(比如跑车、SUV)。
- 使用 建造者模式 来封装"组装过程"。
cpp
#include <iostream>
#include <string>
using namespace std;
// ================= Product: 汽车 =================
class Car {
public:
void setEngine(const string &e) { engine = e; }
void setWheels(const string &w) { wheels = w; }
void setBody(const string &b) { body = b; }
void show() {
cout << "这是一辆车: "
<< body << ", " << engine << ", " << wheels << endl;
}
private:
string engine;
string wheels;
string body;
};
// ================= Builder 抽象建造者 =================
class Builder {
public:
virtual ~Builder() {}
virtual void buildEngine() = 0;
virtual void buildWheels() = 0;
virtual void buildBody() = 0;
virtual Car* getResult() = 0;
};
// ================= 具体建造者: 跑车 =================
class SportsCarBuilder : public Builder {
public:
SportsCarBuilder() { car = new Car(); }
void buildEngine() override { car->setEngine("V8 发动机"); }
void buildWheels() override { car->setWheels("18寸跑车轮胎"); }
void buildBody() override { car->setBody("流线型跑车车身"); }
Car* getResult() override { return car; }
private:
Car *car;
};
// ================= 具体建造者: SUV =================
class SUVBuilder : public Builder {
public:
SUVBuilder() { car = new Car(); }
void buildEngine() override { car->setEngine("V6 涡轮发动机"); }
void buildWheels() override { car->setWheels("20寸越野轮胎"); }
void buildBody() override { car->setBody("高底盘SUV车身"); }
Car* getResult() override { return car; }
private:
Car *car;
};
// ================= Director 指挥者 =================
class Director {
public:
Director(Builder *b) : builder(b) {}
Car* construct() {
builder->buildEngine();
builder->buildWheels();
builder->buildBody();
return builder->getResult();
}
private:
Builder *builder;
};
// ================= 使用示例 =================
int main() {
// 生产跑车
Builder *sportsBuilder = new SportsCarBuilder();
Director director1(sportsBuilder);
Car *sportsCar = director1.construct();
sportsCar->show();
// 生产SUV
Builder *suvBuilder = new SUVBuilder();
Director director2(suvBuilder);
Car *suvCar = director2.construct();
suvCar->show();
delete sportsCar;
delete sportsBuilder;
delete suvCar;
delete suvBuilder;
return 0;
}
