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

生成器建造者模式(Builder)——创建型模式

生成器/建造者模式——创建型模式

什么是生成器模式?

生成器模式是一种创建型设计模式, 使你能够分步骤创建复杂对象。 该模式允许你使用相同的创建代码生成不同类型和形式的对象。

提炼两个关键点:Ⅰ.分步骤创建复杂对象。Ⅱ.相同创建代码创建不同类型和形式的对象。

Ⅰ.分步骤创建复杂对象:

假设有一个产品类,这个产品有100个非静态成员属性,为了保证程序的健壮性,我们要在构造函数中对这100个属性进行init。此时构造函数"又大又长"不说,我们在调用时还要逐一去找准参数顺序,并且如果想设置一些默认值,还要去重载构造函数设置缺省参数,真的是极其复杂。

生成器模式就是把创建的行为抽象出来,抽象出两个类,分别是生成器(builder)和主管(director)。

生成器(builder):生成器类中依赖于某个产品(产品加工器),内部包含一个产品实体,并实现了"一堆"set方法用于设置产品属性字段,并对外**提供getproduct()**方法。

主管(director): 主管类中实现的是产品的参数设置方法(相当于人拿着产品参数说明书)。主管有很多说明书(idea),面对同一个生成器,设置参数不同,构造出的产品就不同。也就是说操作生成器的动作在主管类的成员方法中

总结:在CodeClient中,我们只需要定义一个生成器和一个主管,就可以根据主管的不同想法操作同一个生成器生成不同参数的产品。又因为对每个字段设置的操作都实现成独立的方法,所以我们需要考虑设置顺序,需要哪个调用哪个即可。

Ⅱ.相同创建代码创建不同类型和形式的对象:

简单来说,主管的某一个想法,可以作用到不同的生成器上。比如说主管类根据自己的产品参数说明书操作汽车生成器,来生成一台汽车。那同样可以用这个产品参数说明书操作汽车手册生成器,生成一个汽车手册对象。因为对于手册和汽车实体,字段几何都是一样的,比如说几个座位、几个门、是否有GPS…,只不过字段类型可能不同。

用C++实现一个例子:

在这里插入图片描述

/*************************************************************************
        > File Name: builder.cpp
        > Author:
        > Mail:
        > Created Time: Tue Mar 12 10:54:06 2024
 ************************************************************************/

#include <iostream>
#include <cstring>
using namespace std;

class Car {
public:
    int seatnum;
    int doornum;
    bool GPS;
};

class Manual {
public:
    string seatnum;
    string doornum;
    string GPS;
};

class Builder {
public:
    virtual void setSeats(int) = 0;
    virtual void setDoors(int) = 0;
    virtual void setGPS(bool) = 0;
};

class CarBuilder : public Builder {
private:
    Car car;
public:
    void setSeats(int num) override {
        car.seatnum = num;
    }
    void setDoors(int num) override {
        car.doornum = num;
    }
    void setGPS(bool is) override {
        car.GPS = is;
    }
    Car getCarIns() {
        return car;
    }
};

class ManualBuilder : public Builder {
private:
    Manual manual;
public:
    void setSeats(int num) override {
        manual.seatnum = "This car has " + to_string(num) + " seat.";
    }
    void setDoors(int num) override {
        manual.doornum = "This car has " + to_string(num) + " door.";
    }
    void setGPS(bool is) override {
        if (is)  manual.GPS = "Support GPS";
        else manual.GPS = "No support GPS";
    }
    Manual getManualIns() {
        return manual;
    }
};

class Director {
public:
    void makeSUV(Builder &builder) {
        builder.setSeats(4);
        builder.setDoors(4);
        builder.setGPS(true);
    }
    void makeSports(Builder &builder) {
        builder.setSeats(2);
        builder.setDoors(2);
        builder.setGPS(false);
    }
};

void CodeClient() {
    Director director;

    CarBuilder carbuilder;
    director.makeSUV(carbuilder);
    Car car = carbuilder.getCarIns();
    cout << car.seatnum << endl << car.doornum << endl << car.GPS << endl;

    ManualBuilder manualbuilder;
    director.makeSports(manualbuilder);
    Manual manual = manualbuilder.getManualIns();
    cout << manual.seatnum << endl << manual.doornum << endl << manual.GPS << endl;

    return ;
}

int main() {
    CodeClient();
    return 0;
}

http://www.kler.cn/a/272590.html

相关文章:

  • 2025.1.17——三、SQLi regexp正则表达式|
  • dl学习笔记:(4)简单神经网络
  • 语义检索效果差?深度学习rerank VS 统计rerank选哪个
  • 【Pytorch实用教程】TCN(Temporal Convolutional Network,时序卷积网络)简介
  • vue编写一个可拖动的模块,并可以和任何其他组件组合使用
  • 【数据库】国产达梦数据库与mysql特点、区别、发展前景
  • QT 如何防止 QTextEdit 自动滚动到最下方
  • modbus客户端
  • Tensorflow笔记(二):激活函数、优化器等、神经网络模型实现(商品销量预测)
  • C/C++程序设计实验报告3 | 数组实验
  • FPGA高端项目:FPGA基于GS2971+GS2972架构的SDI视频收发+HLS多路视频融合叠加,提供1套工程源码和技术支持
  • 配置LVS NAT模式
  • 单据分页的实现
  • 机试:高精度乘法
  • 【数据库】数据库基本知识
  • Vue3项目部署安装
  • Redis是如何实现持久化的?请解释RDB和AOF持久化方式的区别和优缺点。Redis是单线程还是多线程的?为什么Redis使用单线程模型仍然能保持高性能?
  • 鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:TimePicker)
  • Spring Boot(七十):利用Jasypt对数据库连接进行加密
  • esp32蜂鸣器进行周期性鸣叫
  • Linux 时间系统调用
  • Android VINF和兼容性矩阵
  • 【自学用】B站python爬虫课程笔记(Q11-15)
  • 一个新名词之CSS高度塌陷
  • PyCluster 问题和解决方案
  • 【ElasticSearch】sping框架集成