• 生成器建造者模式(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 
    #include 
    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
  • 相关阅读:
    探讨Socks5代理技术的原理及其在不同领域的应用
    【基于Qt和OpenCV的多线程图像识别应用】
    HTTPS建立连接的过程
    es之null_value
    Unity-ProBuilder
    关于AbstractQueuedSynchronizer(JDK1.8)的一点理解.
    T31开发笔记: 移动侦测
    Ubuntu 20.04出现蓝牙无法打开的问题(已解决)
    人工神经网络的典型模型,人工神经网络模型定义
    JavaWeb开发06-原理-Spring配置优先级-Bean管理-SpringBoot原理-Maven继承和聚合-私服
  • 原文地址:https://blog.csdn.net/qq_40342400/article/details/136682040