当前位置: 首页 > news >正文

设计模式:建造者模式

文章目录

    • 一、建造者模式的基本概念
    • 二、建造者模式结构
    • 三、示例代码

一、建造者模式的基本概念

  建造者模式(亦称:生成器模式)是一种创建型设计模式, 使你能够分步骤创建复杂对象。 该模式允许你使用相同的创建代码生成不同类型和形式的对象。 将一个复杂对象的构建过程与它的表示 分离,使得同样的构建过程可以创建不同的表示。

  • 意图:处理复杂对象的创建问题,尤其是需要分步骤组装的对象。
  • 核心思想:把复杂对象的创建过程抽象出来,使用不同的“建造者”来构造不同的表示。

在这里插入图片描述
使用场景:

  • 对象构建复杂:对象有很多组成部分,且构建步骤固定,但具体实现不同。
  • 同样的构建过程,不同的表示:比如:
    • 游戏中创建不同风格的角色(武士、法师)。
    • 生成不同格式的报表(PDF、HTML、Excel)。
    • 组装汽车(跑车、越野车)。

总结:

  • 建造者模式更适合“复杂对象的分步骤组装”。
  • 相比工厂模式,建造者模式更关注“组装过程”。

二、建造者模式结构

角色组成:
在这里插入图片描述

  • Product(产品类):最终要创建的复杂对象;由多个部件组成。
  • Builder(抽象建造者):规定创建产品的抽象步骤(通常有 buildPartA()、buildPartB() 等)。不涉及具体部件的实现。
  • ConcreteBuilder(具体建造者):实现 Builder 的接口,具体完成产品部件的创建。最终返回一个完整的 Product。
  • Director(指挥者):调用建造者的步骤方法,控制构建过程。不关心具体的产品细节,只负责组装。

UML类图:
在这里插入图片描述
说明:

  • Product(抽象产品):定义了产品的公共接口。
  • ConcreteProductA / ConcreteProductB(具体产品):实现 Product 接口,不同的产品有不同的行为。
  • Factory(工厂类):提供一个静态方法 createProduct(type),根据参数决定创建哪一种 Product 实例。

三、示例代码

3.1基本示例

#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 界面(包含标题、按钮、输入框等)
需求场景:

  • 我们要创建一个 不同风格的界面(比如 登录界面、注册界面)。
  • 构建过程是固定的:添加标题 → 添加输入框 → 添加按钮。
  • 使用建造者模式来灵活组装。

示例代码:

#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);// 选择不同的 BuilderBuilder *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)。
  • 使用 建造者模式 来封装“组装过程”。
#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();// 生产SUVBuilder *suvBuilder = new SUVBuilder();Director director2(suvBuilder);Car *suvCar = director2.construct();suvCar->show();delete sportsCar;delete sportsBuilder;delete suvCar;delete suvBuilder;return 0;
}

在这里插入图片描述

http://www.dtcms.com/a/348300.html

相关文章:

  • linux下camera 详细驱动流程 OV02K10为例(chatgpt版本)
  • css3之flex布局
  • 在 Ruby 客户端里用 ES|QL
  • 知识蒸馏 Knowledge Distillation 0. 基础:自回归分解与逐 token散度
  • 重学python之mro
  • 【科研绘图系列】R语言浮游植物初级生产力与光照强度的关系
  • 28.原型
  • 详解triton.jit及PTX
  • 目标检测数据集 第006期-基于yolo标注格式的汽车事故检测数据集(含免费分享)
  • vue 自定义文件选择器组件- 原生 input实现
  • 一文学习和掌握网关SpringCloudGateway
  • Java基础知识(五)
  • 南科大C++ 第二章知识储备
  • 电脑深度清理软件,免费磁盘优化工具
  • Shell脚本-如何生成随机数
  • 设置接收超时(SO_RCVTIMEO)
  • 8月精选!Windows 11 25H2 【版本号:26200.5733】
  • 牛市阶段投资指南
  • ffmpeg强大的滤镜功能
  • SingleFile网页保存插件本地安装(QQ浏览器)
  • 【图像处理基石】如何把非笑脸转为笑脸?
  • ffmpeg 问答系列-> mux 部分
  • 启动Flink SQL Client并连接到YARN集群会话
  • Node.js自研ORM框架深度解析与实践
  • 柱状图中最大的矩形+单调栈
  • STM32 入门实录:macOS 下从 0 到点亮 LED
  • Java全栈开发面试实录:从基础到实战的深度探讨
  • 微服务-19.什么是网关
  • 【论文阅读】AI 赋能基于模型的系统工程研究现状与展望
  • Redis--day12--黑马点评--附近商铺用户签到UV统计