【二】【设计模式】建造者模式

建造者模式的引入

 
  
//C10_1.cpp
#include 

#include "SystemConfig.h"

int main() {
        SystemConfig config("mysql://127.0.0.1/", "xiaomu", "xiaomumemeda",
                "redis://127.0.0.1/", "xiaomuredis", "xiaomuredispw",
                "kafka://127.0.0.1", "xiaomukafka", "xiaomukafkapw");

        SystemConfig config2("mysql://127.0.0.1/", "xiaomu", "xiaomumemeda",
                "", "", "",
                "kafka://127.0.0.1", "xiaomukafka", "xiaomukafkapw");


        SystemConfig config3("mysql://127.0.0.1/", "xiaomu", "xiaomumemeda",
                "kafka://127.0.0.1", "xiaomukafka", "xiaomukafkapw",
                "", "", "");
        return 0;
}

C10_1.cpp中,首先包含了SystemConfig.h头文件以访问SystemConfig类。然后在main函数中,创建了三个SystemConfig对象,每个对象都用不同的参数初始化。这三个对象分别为configconfig2config3,它们代表不同的配置集。每个对象的构造函数都传入了MySQL、Redis和Kafka的URL、用户名和密码。在config2config3中,某些服务的参数为空字符串,表示不使用该服务。

 
  
//SystemConfig.h
#pragma once

#include 

class SystemConfig
{
public:
        SystemConfig(const std::string & _MySQL_URL, const std::string & _MySQL_USER, const std::string & _MySQL_PW,
                const std::string & _Redis_URL, const std::string & _Redis_USER, const std::string & _Redis_PW,
                const std::string& _Kafka_URL, const std::string& _Kafka_USER, const std::string& _Kafka_PW);

        std::string MySQL_URL;
        std::string MySQL_USER;
        std::string MySQL_PW;

        std::string Redis_URL;
        std::string Redis_USER;
        std::string Redis_PW;

        std::string Kafka_URL;
        std::string Kafka_USER;
        std::string Kafka_PW;
};

SystemConfig.hSystemConfig类的头文件。它声明了SystemConfig类及其构造函数和成员变量。构造函数接受MySQL、Redis和Kafka的URL、用户名和密码作为参数。这些参数被用来初始化对象的公共成员变量。使用#pragma once防止头文件被多次包含。

 
  
//SystemConfig.cpp
#include "SystemConfig.h"

SystemConfig::SystemConfig(const std::string& _MySQL_URL, const std::string& _MySQL_USER, const std::string& _MySQL_PW,
        const std::string& _Redis_URL, const std::string& _Redis_USER, const std::string& _Redis_PW,
        const std::string& _Kafka_URL, const std::string& _Kafka_USER, const std::string& _Kafka_PW)
{
        MySQL_URL = _MySQL_URL;
        MySQL_USER = _MySQL_USER;
        MySQL_PW = _MySQL_PW;

        Redis_USER = _Redis_USER;
        Redis_URL = _Redis_URL;
        Redis_PW = _Redis_PW;

        Kafka_USER = _Kafka_USER;
        Kafka_URL = _Kafka_URL;
        Kafka_PW = _Kafka_PW;
}

SystemConfig.cppSystemConfig类的源文件。它定义了SystemConfig类构造函数内部的代码逻辑,利用接受的MySQL、Redis和Kafka的URL、用户名和密码的参数,对应的赋值给SystemConfig类的成员变量。

建造者模式

 
  
//C10_2.cpp
#include 

#include "SystemConfig.h"

#include "SystemConfigBuilder.h"

#include "CompanyA.h"
#include "CompanyB.h"

int main()
{
        /*
        SystemConfig config("mysql://127.0.0.1/", "xiaomu", "xiaomumemeda",
                                                "redis://127.0.0.1/", "xiaomuredis", "xiaomuredispw",
                                                "kafka://127.0.0.1", "xiaomukafka", "xiaomukafkapw");

        SystemConfig config2;
        config2.setMySQL("mysql://127.0.0.1/", "xiaomu", "xiaomumemeda");
        config2.setRedis("redis://127.0.0.1/", "xiaomuredis", "xiaomuredispw");
        config2.setKafka("kafka://127.0.0.1", "xiaomukafka", "xiaomukafkapw");
        */

        SystemConfigBuilder builder; 
        builder.setMySQL("mysql://127.0.0.1/", "xiaomu", "xiaomumemeda");
        builder.setRedis("redis://127.0.0.1/", "xiaomuredis", "xiaomuredispw");
        builder.setKafka("kafka://127.0.0.1", "xiaomukafka", "xiaomukafkapw");
        SystemConfig config = builder.getSystemConfig();

        printf("Mysql URL: %s\n", config.MySQL_URL.c_str());
        printf("Mysql USER: %s\n", config.MySQL_USER.c_str());
        printf("Mysql PW %s\n", config.MySQL_PW.c_str());

        printf("Redis URL: %s\n", config.Redis_URL.c_str());
        printf("Redis USER: %s\n", config.Redis_USER.c_str());
        printf("Redis PW %s\n", config.Redis_PW.c_str());

        printf("Kafka URL: %s\n", config.Kafka_URL.c_str());
        printf("Kafka USER: %s\n", config.Kafka_USER.c_str());
        printf("Kafka PW %s\n", config.Kafka_PW.c_str());

        CompanyA companyA;
        SystemConfig configA = companyA.buildSystemConfig();

        CompanyB companyB;
        SystemConfig configB = companyB.buildSystemConfig();

        return 0;
}
 
  
//SystemConfig.h
#pragma once

#include 

class SystemConfig
{
public:
        SystemConfig();
        SystemConfig(const std::string & _MySQL_URL, const std::string & _MySQL_USER, const std::string & _MySQL_PW,
                const std::string & _Redis_URL, const std::string & _Redis_USER, const std::string & _Redis_PW,
                const std::string& _Kafka_URL, const std::string& _Kafka_USER, const std::string& _Kafka_PW);

        
        std::string MySQL_URL;
        std::string MySQL_USER;
        std::string MySQL_PW;

        std::string Redis_URL;
        std::string Redis_USER;
        std::string Redis_PW;

        std::string Kafka_URL;
        std::string Kafka_USER;
        std::string Kafka_PW;
};

SystemConfig.hSystemConfig类的头文件。它声明了SystemConfig类及其构造函数和成员变量。构造函数接受MySQL、Redis和Kafka的URL、用户名和密码作为参数。这些参数被用来初始化对象的公共成员变量。使用#pragma once防止头文件被多次包含。与之前的代码一致,没有发生改变。

 
  
//SystemConfig.cpp
#include "SystemConfig.h"

SystemConfig::SystemConfig()
{

}

SystemConfig::SystemConfig(const std::string& _MySQL_URL, const std::string& _MySQL_USER, const std::string& _MySQL_PW,
        const std::string& _Redis_URL, const std::string& _Redis_USER, const std::string& _Redis_PW,
        const std::string& _Kafka_URL, const std::string& _Kafka_USER, const std::string& _Kafka_PW)
{
        MySQL_URL = _MySQL_USER;
        MySQL_USER = _MySQL_URL;
        MySQL_PW = _MySQL_PW;

        Redis_USER = _Redis_USER;
        Redis_URL = _Redis_URL;
        Redis_PW = _Redis_PW;

        Kafka_USER = _Kafka_USER;
        Kafka_URL = _Kafka_URL;
        Kafka_PW = _Kafka_PW;
}

SystemConfig.cppSystemConfig类的源文件。它定义了SystemConfig类构造函数内部的代码逻辑,利用接受的MySQL、Redis和Kafka的URL、用户名和密码的参数,对应的赋值给SystemConfig类的成员变量。

 
  
//SystemConfigBuilder.h
#pragma once

#include "SystemConfig.h"

class SystemConfigBuilder
{
public:
        SystemConfig config;

        int setMySQL(const std::string& _MySQL_URL, const std::string& _MySQL_USER, const std::string& _MySQL_PW);
        int setRedis(const std::string& _Redis_URL, const std::string& _Redis_USER, const std::string& _Redis_PW);
        int setKafka(const std::string& _Kafka_URL, const std::string& _Kafka_USER, const std::string& _Kafka_PW);

        SystemConfig& getSystemConfig();
};

SystemConfigBuilder.hSystemConfigBuilder类的头文件,声明了SystemConfig类成员变量,以及setMySQLsetRedissetKafka,三个成员函数,分别用来配置MySQLRedisKafka。以及getSystemConfig成员函数用来获取对应的SystemConfig类系统配置。

 
  
//SystemConfigBuilder.cpp
#include "SystemConfigBuilder.h"

SystemConfig& SystemConfigBuilder::getSystemConfig()
{
        return config;
}

int SystemConfigBuilder::setMySQL(const std::string& _MySQL_URL, const std::string& _MySQL_USER, const std::string& _MySQL_PW)
{
        config.MySQL_URL = _MySQL_USER;
        config.MySQL_USER = _MySQL_URL;
        config.MySQL_PW = _MySQL_PW;

        return 0;
}

int SystemConfigBuilder::setRedis(const std::string& _Redis_URL, const std::string& _Redis_USER, const std::string& _Redis_PW)
{
        config.Redis_USER = _Redis_USER;
        config.Redis_URL = _Redis_URL;
        config.Redis_PW = _Redis_PW;

        return 0;
}

int SystemConfigBuilder::setKafka(const std::string& _Kafka_URL, const std::string& _Kafka_USER, const std::string& _Kafka_PW)
{
        config.Kafka_USER = _Kafka_USER;
        config.Kafka_URL = _Kafka_URL;
        config.Kafka_PW = _Kafka_PW;

        return 0;
}

SystemConfigBuilder.cppSystemConfigBuilder类的源文件,对SystemConfigBuilder.h中的声明进行了定义。

 
  
//Director.h
#pragma once

#include "SystemConfig.h"
#include "SystemConfigBuilder.h"

class Director
{
public:
        SystemConfigBuilder builder;

        virtual SystemConfig& buildSystemConfig() = 0;
};

Director.hDirector导演类的头文件,我们利用SystemConfigBuilder类可以很方便地完成系统的配置,但对于不同的公司他们提供的服务不同,有些公司只需要配置MySQLKafka,有些公司只配置MySQLRedis。对于不同的公司运用SystemConfigBuilder类的情况不同,因此我们为不同的公司准备不同的调用方案,到时候只需要使用一个函数就可以完成配置。将调用函数配置行为进行封装。

Director的目的是为了封装控制SystemConfigBuilder 类,因此构造一个纯虚函数buildSystemConfig,用来表示不同公司对于SystemConfigBuilder 的使用情况。

 
  
//Director.cpp
#include "Director.h"
 
  
//CompanyA.h
#pragma once

#include "SystemConfig.h"
#include "SystemConfigBuilder.h"

#include "Director.h"

class CompanyA : public Director
{
public:
        virtual SystemConfig & buildSystemConfig() override;
};

 
  
//CompanyA.cpp
#include "CompanyA.h"

SystemConfig& CompanyA::buildSystemConfig()
{
        builder.setMySQL("mysql://127.0.0.1/", "xiaomu", "xiaomumemeda");
        builder.setRedis("", "", "");
        builder.setKafka("kafka://127.0.0.1", "xiaomukafka", "xiaomukafkapw");
        return builder.getSystemConfig();
}

CompanyA公司只配置MySQLKafka,因此buildSystemConfig函数调用setRedis参数为空。

 
  
//CompanyB.h
#pragma once

#include "SystemConfig.h"
#include "SystemConfigBuilder.h"

#include "Director.h"

class CompanyB : public Director
{
public:
        virtual SystemConfig& buildSystemConfig() override;
};

 
  
//CompanyB.cpp
#include "CompanyB.h"

SystemConfig& CompanyB::buildSystemConfig()
{
        builder.setMySQL("mysql://127.0.0.1/", "xiaomu", "xiaomumemeda");
        builder.setRedis("redis://127.0.0.1/", "xiaomuredis", "xiaomuredispw");
        builder.setKafka("", "", "");
        return builder.getSystemConfig();
}

CompanyB公司只配置MySQLRedis,因此buildSystemConfig函数调用setKafka参数为空。

结尾

最后,感谢您阅读我的文章,希望这些内容能够对您有所启发和帮助。如果您有任何问题或想要分享您的观点,请随时在评论区留言。

同时,不要忘记订阅我的博客以获取更多有趣的内容。在未来的文章中,我将继续探讨这个话题的不同方面,为您呈现更多深度和见解。

谢谢您的支持,期待与您在下一篇文章中再次相遇!

你可能感兴趣的:(设计模式,设计模式,建造者模式)