什么是建造者模式?
建造者模式(Builder Pattern)是一种创建型设计模式
,它允许你构造复杂对象步骤分解。你可以不同的步骤中使用不同的方式创建对象,且对象的创建与表示是分离的。这样,同样的构建过程可以创建不同的表示。
在 C++ 中,建造者模式通常涉及到以下几个关键部分:
1.产品(Product) :这是最终要构造的对象。它通常包含很多属性。
2.抽象建造者(Abstract Builder) :这是一个接口,定义了创建产品所需的各个步骤的方法。
3.具体建造者(Concrete Builder) :这是实现抽象建造者接口的具体类。它实现了创建产品所需的各个步骤。
4.导演(Director):这个类负责执行创建产品的整个过程。它使用具体建造者来创建产品的各个部分,并在适当的时候调用它们。
建造者模式和工厂模式的区别?
建造者模式和工厂模式都是创建型设计模式
,但它们的关注点和用途有所不同。以下是它们的主要区别:
1.关注点 :建造者模式注重零部件的组装过程,而工厂方法模式更注重零部件的创建过程
。
2.创建对象的力度 :建造者模式创建复杂的对象,由各种复杂的部件组成,而工厂模式创建出来的对象都一样。
3.顺序 :建造者模式根据建造过程中的顺序不一样,最终的对象部件组成也不一样。而工厂模式则没有这样的关注。
4.使用场景 :创建简单对象时,通常使用工厂模式;创建复杂对象时,可以考虑使用建造者模式。
总的来说,工厂模式更注重对象的创建,而建造者模式更注重对象的组装过程和组成部分。在实际应用中,可以根据需要选择使用哪种设计模式。
建造者模式适用什么场景,举个具体的例子
建造者模式适用于创建具有多个组成部分的复杂对象,尤其是那些需要对个步骤来创建的对象。
假设我们需要创建一个复杂的"电脑"对象,该对象包含多个组成部分,如"CPU"、"内存"、"硬盘"等。我们可以使用建造者模式来创建这个对象,具体步骤如下:
1.首先我们需要一个产品类Computer
,也就是电脑,这是最终要构造的对象,电脑通常包含很多属性也就是组成部分,比如CPU,内存,硬盘这些;例如,在具体电脑建造者中,我们可以调用"Computer"类的"setCPU()"、"setMemory()"和"setHardDisk()"方法来设置电脑的各个组成部分
2.然后,我们定义一个抽象建造者ComputerBuilder
接口,该接口定义了创建电脑对象所需的各个步骤的虚方法。如"buildCPU()"、"buildMemory()"、"buildHardDisk()"等。
3.接下来,我们定义一个具体建造者ConcreteComputerBuilder
类,该类实现了抽象建造者接口中定义的所有方法。在具体建造者中,我们可以按照需要的顺序和方式来创建电脑对象的各个组成部分。
4.然后,我们定义一个导演ComputerDirector
类,该类负责执行创建电脑对象的整个过程。导演类中使用具体建造者来创建电脑对象的各个部分,并在适当的时候调用它们。
5.最后,客户端代码可以使用导演类来创建电脑对象。客户端不需要知道电脑对象内部的具体实现细节,只需要调用导演类提供的方法即可。
代码示例:
c++
#include<iostream>
#include<string>
using namespace std;
//1.产品:电脑
class Computer
{
public:
void setCPU(string cpu) { m_cpu = cpu; }
void setMemory(string memory) { m_memory = memory; }
void setHardDisk(string hardDisk) { m_hardDisk = hardDisk; }
//const位于函数参数列表之后,表示该函数是一个常量成员函数,该函数不会修改任何成员变量的值
void print()const {
std::cout << "CPU: " << m_cpu << ", Memory: " << m_memory << ", Hard Disk: " << m_hardDisk << std::endl;
}
private:
string m_cpu;
string m_memory;
string m_hardDisk;
};
//2.抽象建造者:电脑建造者接口
class ComputerBuilder
{
public:
virtual ~ComputerBuilder() {}; //虚析构,为了销毁父类指针所指向的子类对象
virtual void buildCPU() = 0;
virtual void buildMemory() = 0;
virtual void buildHardDisk() = 0;
virtual Computer* getComputer() = 0;
};
//3.具体建造者:具体的电脑建造者
class ConcreteComputerBuilder :public ComputerBuilder
{
public:
void buildCPU() { m_computer->setCPU("Intel Core i7"); }
void buildMemory() { m_computer->setMemory("16GB DDR4");}
void buildHardDisk() { m_computer->setHardDisk("1TB SSD");}
Computer* getComputer() { return m_computer; }
private:
Computer* m_computer = new Computer;
};
//4.导演:电脑建造导演
class ComputerDirector
{
public:
ComputerDirector(ComputerBuilder* builder) :m_builder(builder) {}
void construct() {
m_builder->buildCPU();
m_builder->buildMemory();
m_builder->buildHardDisk();
}
private:
ComputerBuilder* m_builder;
};
int main()
{
ConcreteComputerBuilder builder;//创建一个具体的电脑对象
ComputerDirector director(&builder); //创建一个导演
director.construct();
builder.getComputer()->print();
delete builder.getComputer();
return 0;
}
手机生产
我现在要生产iphone手机,有iPhone14和iPhone15,各自又有mini和pro两个版本。
c++
#include <iostream>
#include <memory>
//产品类:iphone
class iPhone
{
public:
void setMemory(const std::string& memory) { m_memory = memory; }
void setScreen(const std::string& screen) { m_screen = screen; }
void setAppearance(const std::string& apperance) { m_appearance = apperance; }
void showInfo() const {
std::cout << "Memory: " << m_memory << std::endl;
std::cout << "Screen: " << m_screen << std::endl;
std::cout << "Appearance: " << m_appearance << std::endl;
}
private:
std::string m_memory;
std::string m_screen;
std::string m_appearance;
};
//抽象建造者:iphone手机建造者接口
class iPhoneBuilder
{
public:
virtual void buildMemory() = 0;
virtual void buildScreen() = 0;
virtual void buildAppearance() = 0;
virtual std::unique_ptr<iPhone> getiPhone() = 0;
};
//具体建造者:iPhone14 Mini 建造者
class iPhoneBuilder14Mini :public iPhoneBuilder
{
void buildMemory() { m_memory = "64GB"; }
void buildScreen() { m_screen = "5.4-inch"; }
void buildAppearance() { m_appearance = "Glass back and aluminum frame"; };
std::unique_ptr<iPhone> getiPhone() override
{
std::unique_ptr<iPhone> iphone = std::make_unique<iPhone>();
iphone->setMemory(m_memory);
iphone->setScreen(m_screen);
iphone->setAppearance(m_appearance);
return iphone;
}
private:
std::string m_memory;
std::string m_screen;
std::string m_appearance;
};
//具体建造者:iPhone14 pro 建造者
class iPhoneBuilder14PRO :public iPhoneBuilder
{
void buildMemory() { m_memory = "256GB"; }
void buildScreen() { m_screen = "6.1-inch"; }
void buildAppearance() { m_appearance = "Ceramic back and stainless steel frame"; };
std::unique_ptr<iPhone> getiPhone() override
{
std::unique_ptr<iPhone> iphone = std::make_unique<iPhone>();
iphone->setMemory(m_memory);
iphone->setScreen(m_screen);
iphone->setAppearance(m_appearance);
return iphone;
}
private:
std::string m_memory;
std::string m_screen;
std::string m_appearance;
};
//导演类:生成手机
class Director
{
public:
std::unique_ptr<iPhone> create(iPhoneBuilder& builder)
{
builder.buildMemory();
builder.buildScreen();
builder.buildAppearance();
return builder.getiPhone();
}
};
int main()
{
Director director;
//iphone14 mini
iPhoneBuilder14Mini iphone14mini;
std::unique_ptr<iPhone> mini = director.create(iphone14mini);
std::cout << "iPhone 14 Mini" << std::endl;
mini->showInfo();
std::cout << std::endl;
iPhoneBuilder14PRO iphone14PRO;
std::unique_ptr<iPhone> pro = director.create(iphone14PRO);
std::cout << "iPhone 14 Mini" << std::endl;
pro->showInfo();
std::cout << std::endl;
}
sunny和merry号生产
现在我们开始着手把路飞的海贼船桑尼号 和梅利号使用生成器模式键造出来。
1、一共需要三个生成器类,一共父类,两个子类;
2、父类可以是一个抽象类,提供的建造函数都是虚函数;
3、在两个生成器子类中,使用建造函数分别将桑尼号 和梅利号各个零部件造出来。
如果我们仔细分析,发现还需要解决另外一个问题,通过生成器得到了海贼船的各个零部件,这些零部件必须有一个载体,那就是海贼船对象
。因此,还需要提供一个或多个海贼船类。
因为桑尼号 和梅利号这两艘的差别非常之巨大,所以我们定义两个海贼船类
,代码如下:
csharp
#include <iostream>
#include <memory>
#include <map>
#include <vector>
#include <string>
using namespace std;
/*******************************_两个船类(Sunny号和Merry号)_*************************************/
//产品1:Sunny号
class Sunnyship
{
public:
//添加零件
void addParts(string name)
{
m_parts.push_back(name);
}
void showParts()
{
for (const auto& item : m_parts)
{
cout << item << " ";
cout << endl;
}
}
private:
vector<string> m_parts;
};
//产品2:Merry号
class Merryship
{
public:
//添加零件
void assemble(string name,string parts)
{
m_parts.insert(make_pair(name,parts));
}
void showParts()
{
for (const auto& item : m_parts)
{
cout << item.first << ": "<<item.second << " ";
cout << endl;
}
}
private:
map<string,string> m_parts;
};
/**************************************************************************************************/
/*****************************************_生成器类_*********************************************************/
//抽象生成器类
class ShipBuilder
{
public:
virtual void reset() = 0;
virtual void buildBody() = 0;
virtual void buildWeapon() = 0;
virtual void buildEngine() = 0;
virtual void buildInterior() = 0;
virtual ~ShipBuilder() {}
};
//具体生成器类:Sunny号生成器
class SunnyBuilder :public ShipBuilder
{
public:
SunnyBuilder()
{
reset();
}
~SunnyBuilder()
{
if (m_sunny != nullptr)
{
delete m_sunny;
}
}
void reset() override
{
m_sunny = new Sunnyship;
}
void buildBody()
{
m_sunny->addParts("神树亚当的树干");
}
void buildWeapon()
{
m_sunny->addParts("狮吼炮");
}
void buildEngine()
{
m_sunny->addParts("可乐驱动");
}
void buildInterior()
{
m_sunny->addParts("豪华精装修的内饰");
}
Sunnyship* getSunny()
{
Sunnyship* ship = m_sunny;
m_sunny = nullptr;
return ship;
}
private:
Sunnyship* m_sunny = nullptr;
};
//具体生成器类:Merry号生成器
class MerryBuilder :public ShipBuilder
{
public:
MerryBuilder()
{
reset();
}
~MerryBuilder()
{
if (m_merry != nullptr)
{
delete m_merry;
}
}
void reset() override
{
m_merry = new class Merryship;
}
void buildBody()
{
m_merry->assemble("船体","优质木材");
}
void buildWeapon()
{
m_merry->assemble("武器","四门大炮");
}
void buildEngine()
{
m_merry->assemble("动力","蒸汽机");
}
void buildInterior()
{
m_merry->assemble("内饰","精装修");
}
Merryship* getMerry()
{
Merryship* ship = m_merry;
m_merry = nullptr;
return ship;
}
private:
Merryship* m_merry = nullptr;
};
/******************************************_导演类_***********************************************/
class Director
{
public:
void setBuilder(ShipBuilder* builder)
{
m_builder = builder;
}
void builderSimpleShip()
{
m_builder->buildBody();
m_builder->buildEngine();
}
void builderStandShip()
{
builderSimpleShip();
m_builder->buildWeapon();
}
void builderRegalShip()
{
builderStandShip();
m_builder->buildInterior();
}
private:
ShipBuilder* m_builder = nullptr;
};
/*******************************_代码测试_**************************************************/
//建造Sunny号
void buildSunny()
{
Director director;
SunnyBuilder Sbuild;
//简约型
director.setBuilder(&Sbuild);
director.builderSimpleShip();
Sunnyship* Sship = Sbuild.getSunny();
Sship->showParts();
delete Sship;
}
int main()
{
buildSunny();
}