给网站做镜像,ui设计培训班学费,wordpress编辑器修改,手机中国第一专业门户一 什么是建造者模式#xff1f;
// 小木公司对于SQL有配置#xff0c;因此要输入sql url#xff0c;然后输入 sql username#xff0c;然后是 sql ps //因此小木就想到了使用 SystemConfig这个类来完成上述的三个初始化
//5.1号小木公司加入了redis的缓存机制#xff0…一 什么是建造者模式
// 小木公司对于SQL有配置因此要输入sql url然后输入 sql username然后是 sql ps //因此小木就想到了使用 SystemConfig这个类来完成上述的三个初始化
//5.1号小木公司加入了redis的缓存机制redis也有 urlusernamepassword三个字符串
//10.1之后小木公司加入了kafka机制让log都存储到kafka中kafka也有urlusernamepassword三个字符串
//说不定过年后还有加上其他配置项。这时候小木意识到问题的严重性了 //每次改动都一堆参数且容易出现问题 // 小木公司对于SQL有配置因此要输入sql url然后输入 sql username然后是 sql ps
//因此小木就想到了使用 SystemConfig这个类来完成上述的三个初始化//5.1号小木公司加入了redis的缓存机制redis也有 urlusernamepassword三个字符串//10.1之后小木公司加入了kafka机制让log都存储到kafka中kafka也有urlusernamepassword三个字符串//说不定过年后还有加上其他配置项。这时候小木意识到问题的严重性了
//每次改动都一堆参数且容易出现问题
#include iostream
#include string
using namespace std;class SystemConfig {public:SystemConfig(string sqlurl,string sqlusername,string sqlpassword,string redisurl, string redisusername, string redispassword,string kafkaurl, string kafkausername, string kafkapassword): MySQL_URL(sqlurl), MySQL_username(sqlusername), MySQL_password(sqlpassword),REDIS_URL(redisurl), REDIS_username(redisusername), REDIS_password(redispassword),KAFKA_URL(kafkaurl), KAFKA_username(kafkausername), KAFKA_password(kafkapassword){}void printfSysConfig() {cout MySQL_URL MySQL_URL MySQL_username MySQL_username MySQL_password MySQL_password REDIS_URL REDIS_URL REDIS_username REDIS_username REDIS_password REDIS_password KAFKA_URL KAFKA_URL KAFKA_username KAFKA_username KAFKA_password KAFKA_password endl;}
private:string MySQL_URL;string MySQL_username;string MySQL_password;//5.1之后string REDIS_URL;string REDIS_username;string REDIS_password;//10.1之后string KAFKA_URL;string KAFKA_username;string KAFKA_password;
};//想到的第一解决方案是我们将这些属性都弄成函数class SystemConfig1 {public:SystemConfig1() {}void setMySQLConfig(string sqlurl, string sqlusername, string sqlpassword) {this-MySQL_URL sqlurl;this-MySQL_username sqlusername;this-MySQL_password sqlpassword;}void setRedisConfig(string redisurl, string redisusername, string redispassword) {this-REDIS_URL redisurl;this-REDIS_username redisusername;this-REDIS_password redispassword;}void setKAFKAConfig(string kafkaurl, string kafkausername, string kafkapassword) {this-KAFKA_URL kafkaurl;this-KAFKA_username kafkausername;this-KAFKA_password kafkapassword;}void printfSysConfig() {cout MySQL_URL MySQL_URL MySQL_username MySQL_username MySQL_password MySQL_password REDIS_URL REDIS_URL REDIS_username REDIS_username REDIS_password REDIS_password KAFKA_URL KAFKA_URL KAFKA_username KAFKA_username KAFKA_password KAFKA_password endl;}
private:string MySQL_URL;string MySQL_username;string MySQL_password;//5.1之后string REDIS_URL;string REDIS_username;string REDIS_password;//10.1之后string KAFKA_URL;string KAFKA_username;string KAFKA_password;
};//构造者模式
//创建一个sustemconfig的build类创建systemconfig的过程全都交给这个systemconfig类来实现class SystemConfig2 {
public:SystemConfig2() {}void printfSysConfig() {cout MySQL_URL MySQL_URL MySQL_username MySQL_username MySQL_password MySQL_password REDIS_URL REDIS_URL REDIS_username REDIS_username REDIS_password REDIS_password KAFKA_URL KAFKA_URL KAFKA_username KAFKA_username KAFKA_password KAFKA_password endl;}
public:string MySQL_URL;string MySQL_username;string MySQL_password;//5.1之后string REDIS_URL;string REDIS_username;string REDIS_password;//10.1之后string KAFKA_URL;string KAFKA_username;string KAFKA_password;
};class SystemConfig2Build {public:SystemConfig2Build() {}SystemConfig2 getSystemConfig() {return systemconfig;}void setMySQLConfig(string sqlurl, string sqlusername, string sqlpassword) {systemconfig.MySQL_URL sqlurl;systemconfig.MySQL_username sqlusername;systemconfig.MySQL_password sqlpassword;}void setRedisConfig(string redisurl, string redisusername, string redispassword) {systemconfig.REDIS_URL redisurl;systemconfig.REDIS_username redisusername;systemconfig.REDIS_password redispassword;}void setKAFKAConfig(string kafkaurl, string kafkausername, string kafkapassword) {systemconfig.KAFKA_URL kafkaurl;systemconfig.KAFKA_username kafkausername;systemconfig.KAFKA_password kafkapassword;}private:SystemConfig2 systemconfig;
};class CompanyA {
public:virtual SystemConfig2 buildSystemConfig() {scbuild2.setMySQLConfig(11a, 22a, 33a);scbuild2.setRedisConfig(44a, 55a, 66a);scbuild2.setKAFKAConfig(77a, 88a, 99a);return scbuild2.getSystemConfig();}private:SystemConfig2Build scbuild2;
};class CompanyB {
public:SystemConfig2 buildSystemConfig() {scbuild2.setMySQLConfig(11B, 22B, 33B);scbuild2.setRedisConfig(44B, 55B, 66B);scbuild2.setKAFKAConfig(77B, 88B, 99B);return scbuild2.getSystemConfig();}private:SystemConfig2Build scbuild2;
};class CompanyDiect {
public:virtual SystemConfig2 buildSystemConfig() 0;virtual ~CompanyDiect() {//注意父类的 析构函数 要写成 virtual形式的。}
private:SystemConfig2Build scbuild2;
};//c公司
class CompanyDiectc:public CompanyDiect {
public:virtual SystemConfig2 buildSystemConfig() {scbuild2.setMySQLConfig(11c, 22c, 33c);scbuild2.setRedisConfig(44c, 55c, 66c);scbuild2.setKAFKAConfig(77c, 88c, 99c);return scbuild2.getSystemConfig();}private:SystemConfig2Build scbuild2;
};class CompanyDiectd :public CompanyDiect {
public:virtual SystemConfig2 buildSystemConfig() {scbuild2.setMySQLConfig(11d, 22d, 33d);scbuild2.setRedisConfig(44d, 55d, 66d);scbuild2.setKAFKAConfig(77d, 88d, 99d);return scbuild2.getSystemConfig();}private:SystemConfig2Build scbuild2;
};int main()
{_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);//程序退出时检测内存泄漏并显示到“输出”窗口std::cout Hello World!\n;SystemConfig sc SystemConfig(aa,bb,cc,dd,ee,ff,11,22,33);sc.printfSysConfig();//首先想到的fix方案但是有个问题就是开出来了public接口让user可以调用这不怎么好。//也就是说破坏了原有的systemConfig的封装性让user可以有机会再次改动。虽然不得不这么干。SystemConfig1 sc1 SystemConfig1();sc1.setMySQLConfig(SQL11, SQL22, SQL33);sc1.setRedisConfig(redis1, redis2, redis3);sc1.setKAFKAConfig(kafka1, kafka2, kafka3);sc1.printfSysConfig();//构造者模式的调用SystemConfig2Build scbuild2;scbuild2.setMySQLConfig(11, 22, 33);scbuild2.setRedisConfig(44, 55, 66);scbuild2.setKAFKAConfig(77, 88, 99);SystemConfig2 sc2 scbuild2.getSystemConfig();sc2.printfSysConfig();//我们看到上述构造者模式的调用每次都要传递参数进入实际开发中我们可能对于AB公司的配置基本是不变的也就是说我们需要一些预选项CompanyA ca;SystemConfig2 sca ca.buildSystemConfig();sca.printfSysConfig();//B公司CompanyB cB;SystemConfig2 scB cB.buildSystemConfig();scB.printfSysConfig();//我们看代码知道 CompanyA 和 CompanyB 的代码是完全一样的因此可以抽取成父类这样CompanyDiect * comabs;comabs new CompanyDiectc(); //多态完成SystemConfig2 scconn comabs-buildSystemConfig();scconn.printfSysConfig();delete comabs;} 建造者模式也被成为⽣成器模式是⼀种创建型设计模式软件开发过程中有的时候需要创建很复杂的对象⽽建造者模式的主要思想是将对象的构建过程分为多个步骤并为每个步骤定义⼀个抽象的接⼝。具体的构建过程由实现了这些接⼝的具体建造者类来完成。同时有⼀个指导者类负责协调建造者的⼯作按照⼀定的顺序或逻辑来执⾏构建步骤最终⽣成产品。 举个例⼦假如我们要创建⼀个计算机对象计算机由很多组件组成例如 CPU、内存、硬盘、显卡等。每个组件可能有不同的型号、配置和制造这个时候计算机就可以被视为⼀个复杂对象构建过程相对复杂⽽我们使⽤建造者模式将计算机的构建过程封装在⼀个具体的建造者类中⽽指导者类则负责指导构建的步骤和顺序。每个具体的建造者类可以负责构建不同型号或配置的计算机客户端代码可以通过选择不同的建造者来创建不同类型的计算机这样就可以根据需要构建不同表示的复杂对象更加灵活。 假设我们要创建一个计算机对象普通的写法如下
// 004构建者模式.cpp : 此文件包含 main 函数。程序执行将在此处开始并结束。
//#include iostream
#include string
using namespace std;//cpu
class CPU {
public:CPU(string cpuname) :_cpuname(cpuname) {cout CPU 构造方法被调用 _cpuname _cpuname endl;}
public:string _cpuname;};class Memory {
public:Memory(string memname) :_memname(memname) {cout Memory 构造方法被调用 _memname memname endl;}
public:string _memname;
};class Harddisk {
public:Harddisk(string diskname) :_diskname(diskname) {cout Harddisk 构造方法被调用 diskname diskname endl;}
public:string _diskname;
};class GraphicsCard {
public:GraphicsCard(string gcname) :_gcname(gcname) {cout GraphicsCard 构造方法被调用 _gcname _gcname endl;}
public:string _gcname;
};//如果是普通的写法
//假如我们要创建⼀个计算机对象计算机由很多组件组成
//例如 CPU、内存、硬盘、显卡等。
//每个组件可能有不同的型号、配置和制造
//这个时候计算机就可以被视为⼀个复杂对象
class Computer {
public:Computer(CPU *cpu, Memory *mem, Harddisk *hdisk, GraphicsCard *gc):_cpu(cpu),_mem(mem),_hdisk(hdisk),_gc(gc) {cout Computer 构造方法被调用 endl;}~Computer() {cout Computer 析构方法被调用 endl;}void printfCom() {cout cpu this-_cpu-_cpuname mem this-_mem-_memname hdisk this-_hdisk-_diskname gc this-_gc-_gcnameendl;}
protected:CPU *_cpu;Memory *_mem;Harddisk *_hdisk;GraphicsCard *_gc;
};int main()
{std::cout Hello World!\n;CPU cpu(intelcpu);Memory mem(sanxingmem);Harddisk disk(xindisk);GraphicsCard gc(huaweixianka);Computer comA(cpu,mem,disk,gc);comA.printfCom();//这里有个问题如果我们创建的cpmputer比较多又有不同的型号那么很容易写错。//创建者模型就是解决这个问题
} 和继承的写法结合在一起 // 004构建者模式正确的写法.cpp : 此文件包含 main 函数。程序执行将在此处开始并结束。
//#include iostream
#include string
using namespace std;//使用构造者模式创建
class CPUBase {
public:CPUBase(string cpuname) :_cpuname(cpuname) {cout CPUBase 构造方法被调用 _cpuname _cpuname endl;}public:string _cpuname;
};class HuaweiCpu : public CPUBase {
public:HuaweiCpu(string cpuname) :CPUBase(cpuname) {cout HuaweiCpu 构造方法被调用 _cpuname _cpuname endl;}
};
class xiaomiCpu : public CPUBase {
public:xiaomiCpu(string cpuname) :CPUBase(cpuname) {cout xiaomiCpu 构造方法被调用 _cpuname _cpuname endl;}
};
class lianxiangCpu : public CPUBase {
public:lianxiangCpu(string cpuname) :CPUBase(cpuname) {cout lianxiangCpu 构造方法被调用 _cpuname _cpuname endl;}
};class MemoryBase {
public:MemoryBase(string memname) :_memname(memname) {cout MemoryBase 构造方法被调用 _memname memname endl;}
public:string _memname;
};
class huaweiMemory :public MemoryBase {
public:huaweiMemory(string memname) :MemoryBase(memname) {cout huaweiMemory 构造方法被调用 _memname memname endl;}
};
class xiaomiMemory :public MemoryBase {
public:xiaomiMemory(string memname) :MemoryBase(memname) {cout xiaomiMemory 构造方法被调用 _memname memname endl;}
};
class lianxiangMemory :public MemoryBase {
public:lianxiangMemory(string memname) :MemoryBase(memname) {cout lianxiangMemory 构造方法被调用 _memname memname endl;}
};class HarddiskBase {
public:HarddiskBase(string diskname) :_diskname(diskname) {cout HarddiskBase 构造方法被调用 diskname diskname endl;}
public:string _diskname;
};
class huaweiHarddisk :public HarddiskBase {
public:huaweiHarddisk(string diskname) :HarddiskBase(diskname) {cout huaweiHarddisk 构造方法被调用 _diskname diskname endl;}
};
class xiaomiHarddisk :public HarddiskBase {
public:xiaomiHarddisk(string diskname) :HarddiskBase(diskname) {cout xiaomiHarddisk 构造方法被调用 diskname diskname endl;}
};
class lianxiangHarddisk :public HarddiskBase {
public:lianxiangHarddisk(string diskname) :HarddiskBase(diskname) {cout lianxiangHarddisk 构造方法被调用 diskname diskname endl;}
};class GraphicsCardBase {
public:GraphicsCardBase(string gcname) :_gcname(gcname) {cout GraphicsCardBase 构造方法被调用 _gcname _gcname endl;}
public:string _gcname;
};
class huaweiGraphicsCard :public GraphicsCardBase {
public:huaweiGraphicsCard(string gcname) :GraphicsCardBase(gcname) {cout huaweiHarddisk 构造方法被调用 gcname gcname endl;}
};
class xiaomiGraphicsCard :public GraphicsCardBase {
public:xiaomiGraphicsCard(string gcname) :GraphicsCardBase(gcname) {cout xiaomiGraphicsCard 构造方法被调用 gcname gcname endl;}
};
class lianxiangGraphicsCard :public GraphicsCardBase {
public:lianxiangGraphicsCard(string gcname) :GraphicsCardBase(gcname) {cout lianxiangGraphicsCard 构造方法被调用 gcname gcname endl;}
};class ComputerBase {public:virtual ~ComputerBase() {};void printComputerBase() {cout _cpuBase this-_cpuBase _memBase this-_memBase _hdiskBase this-_hdiskBase _gcBase this-_gcBase endl;}// 一般需要给私有的成员属性提供读写接口CPUBase* GetCPUBase() {return this-_cpuBase;}void SetCPUBase(CPUBase* cpubase) {this-_cpuBase cpubase;}MemoryBase* GetMemoryBase() {return this-_memBase;}void SetMemoryBase(MemoryBase* membase) {this-_memBase membase;}HarddiskBase* GetHarddiskBase() {return this-_hdiskBase;}void SetHarddiskBase(HarddiskBase* hdiskBase) {this-_hdiskBase hdiskBase;}GraphicsCardBase* GetGraphicsCardBase() {return this-_gcBase;}void SetGraphicsCardBase(GraphicsCardBase* gcBase) {this-_gcBase gcBase;}protected:CPUBase *_cpuBase;MemoryBase *_memBase;HarddiskBase *_hdiskBase;GraphicsCardBase *_gcBase;
};class huaweiComputer :public ComputerBase {};class lianxiangComputer :public ComputerBase {};class xiaomiComputer :public ComputerBase {};//构建器父类
class ComputerBaseBuilder {
public:virtual ~ComputerBaseBuilder() {};virtual void loadCPU(string cpubase) 0;virtual void loadMem(string membase) 0;virtual void loaddisk(string diskbase) 0;virtual void loadGraphicsCard(string graphicsCardbase) 0;ComputerBase * getCompBase() {return m_compBase;}
protected:ComputerBase *m_compBase;
};class huaweiComputerBuild :public ComputerBaseBuilder {
public:huaweiComputerBuild() {m_compBase new huaweiComputer();}virtual void loadCPU(string strmodelno) {CPUBase *cpu nullptr;if (strmodelno 001) {cpu new HuaweiCpu(huaweicpu);}if (strmodelno 002) {cpu new xiaomiCpu(xiaomicpu);}if (strmodelno 003) {cpu new lianxiangCpu(lianxiangcpu);}cout huaweiComputerBuild loadCPU endl;m_compBase-SetCPUBase(cpu);}virtual void loadMem(string strmodelno) {MemoryBase *memBase nullptr;if (strmodelno 001) {memBase new huaweiMemory(huaweimemory);}if (strmodelno 002) {memBase new xiaomiMemory(xiaomimemory);}if (strmodelno 003) {memBase new lianxiangMemory(lianxiangmemory);}cout huaweiComputerBuild loadmemory endl;m_compBase-SetMemoryBase(memBase);}virtual void loaddisk(string strmodelno) {HarddiskBase *hdiskBase nullptr;if (strmodelno 001) {hdiskBase new huaweiHarddisk(huaweidisk);}if (strmodelno 002) {hdiskBase new xiaomiHarddisk(xiaomidisk);}if (strmodelno 003) {hdiskBase new lianxiangHarddisk(lianxiangdisk);}cout huaweiComputerBuild loaddisk endl;m_compBase-SetHarddiskBase(hdiskBase);}virtual void loadGraphicsCard(string strmodelno) {GraphicsCardBase *_gcBase nullptr;if (strmodelno 001) {_gcBase new huaweiGraphicsCard(huaweigc);}if (strmodelno 002) {_gcBase new xiaomiGraphicsCard(huaweigc);}if (strmodelno 003) {_gcBase new lianxiangGraphicsCard(huaweigc);}cout huaweiComputerBuild loadgcbase endl;m_compBase-SetGraphicsCardBase(_gcBase);}~huaweiComputerBuild() {}
};class lianxiangComputerBuild :public ComputerBaseBuilder {
public:lianxiangComputerBuild() {m_compBase new lianxiangComputer();}virtual void loadCPU(string strmodelno) {CPUBase *cpu nullptr;if (strmodelno 001) {cpu new HuaweiCpu(huaweicpu);}if (strmodelno 002) {cpu new xiaomiCpu(xiaomicpu);}if (strmodelno 003) {cpu new lianxiangCpu(lianxiangcpu);}cout huaweiComputerBuild loadCPU endl;m_compBase-SetCPUBase(cpu);}virtual void loadMem(string strmodelno) {MemoryBase *memBase nullptr;if (strmodelno 001) {memBase new huaweiMemory(huaweimemory);}if (strmodelno 002) {memBase new xiaomiMemory(xiaomimemory);}if (strmodelno 003) {memBase new lianxiangMemory(lianxiangmemory);}cout huaweiComputerBuild loadmemory endl;m_compBase-SetMemoryBase(memBase);}virtual void loaddisk(string strmodelno) {HarddiskBase *hdiskBase nullptr;if (strmodelno 001) {hdiskBase new huaweiHarddisk(huaweidisk);}if (strmodelno 002) {hdiskBase new xiaomiHarddisk(xiaomidisk);}if (strmodelno 003) {hdiskBase new lianxiangHarddisk(lianxiangdisk);}cout huaweiComputerBuild loaddisk endl;m_compBase-SetHarddiskBase(hdiskBase);}virtual void loadGraphicsCard(string strmodelno) {GraphicsCardBase *_gcBase nullptr;if (strmodelno 001) {_gcBase new huaweiGraphicsCard(huaweigc);}if (strmodelno 002) {_gcBase new xiaomiGraphicsCard(huaweigc);}if (strmodelno 003) {_gcBase new lianxiangGraphicsCard(huaweigc);}cout huaweiComputerBuild loadgcbase endl;m_compBase-SetGraphicsCardBase(_gcBase);}~lianxiangComputerBuild() {}
};class xiaomiComputerBuild :public ComputerBaseBuilder {
public:xiaomiComputerBuild() {m_compBase new xiaomiComputer();}virtual void loadCPU(string strmodelno) {CPUBase *cpu nullptr;if (strmodelno 001) {cpu new HuaweiCpu(huaweicpu);}if (strmodelno 002) {cpu new xiaomiCpu(xiaomicpu);}if (strmodelno 003) {cpu new lianxiangCpu(lianxiangcpu);}cout huaweiComputerBuild loadCPU endl;m_compBase-SetCPUBase(cpu);}virtual void loadMem(string strmodelno) {MemoryBase *memBase nullptr;if (strmodelno 001) {memBase new huaweiMemory(huaweimemory);}if (strmodelno 002) {memBase new xiaomiMemory(xiaomimemory);}if (strmodelno 003) {memBase new lianxiangMemory(lianxiangmemory);}cout huaweiComputerBuild loadmemory endl;m_compBase-SetMemoryBase(memBase);}virtual void loaddisk(string strmodelno) {HarddiskBase *hdiskBase nullptr;if (strmodelno 001) {hdiskBase new huaweiHarddisk(huaweidisk);}if (strmodelno 002) {hdiskBase new xiaomiHarddisk(xiaomidisk);}if (strmodelno 003) {hdiskBase new lianxiangHarddisk(lianxiangdisk);}cout huaweiComputerBuild loaddisk endl;m_compBase-SetHarddiskBase(hdiskBase);}virtual void loadGraphicsCard(string strmodelno) {GraphicsCardBase *_gcBase nullptr;if (strmodelno 001) {_gcBase new huaweiGraphicsCard(huaweigc);}if (strmodelno 002) {_gcBase new xiaomiGraphicsCard(xiaomigc);}if (strmodelno 003) {_gcBase new lianxiangGraphicsCard(lianxianggc);}cout huaweiComputerBuild loadgcbase endl;m_compBase-SetGraphicsCardBase(_gcBase);}~xiaomiComputerBuild() {}
};//指挥者类
class ComputerDirector {public:ComputerDirector(ComputerBaseBuilder *computerBaseBuilder) {this-m_pComputerBaseBuilder computerBaseBuilder;}//指定新的构建器void SetBuilder(ComputerBaseBuilder* ptmpBuilder){m_pComputerBaseBuilder ptmpBuilder;}//原MonsterBuilder类中的Assemble成员函数ComputerBase *Construct(string strmodelno) //参数:模型编号形如“002001003001”等。每些位的组合都有一些特别的含义这里不需要探究。{m_pComputerBaseBuilder-loadCPU(strmodelno.substr(0, 3));m_pComputerBaseBuilder-loadMem(strmodelno.substr(3, 3));m_pComputerBaseBuilder-loaddisk(strmodelno.substr(6, 3));m_pComputerBaseBuilder-loadGraphicsCard(strmodelno.substr(9, 3));return m_pComputerBaseBuilder-getCompBase();}private:ComputerBaseBuilder* m_pComputerBaseBuilder; //指向所有构建器类的父类
};int main()
{_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);//程序退出时检测内存泄漏并显示到“输出”窗口xiaomiComputerBuild* xiaocomp new xiaomiComputerBuild();ComputerDirector *cd new ComputerDirector(xiaocomp);ComputerBase *combase cd-Construct(001001001001);delete(combase-GetCPUBase());delete(combase-GetMemoryBase());delete(combase-GetHarddiskBase());delete(combase-GetGraphicsCardBase());combase-printComputerBase();delete combase;delete cd;delete xiaocomp;
}