C++二十三种设计模式之建造者模式
一、组成
抽象产品类 :声明具体产品类功能接口。
具体产品类 :实现抽象产品的功能接口。
抽象建造者类 :持有产品类的引用,声明创建产品各个部件的接口。
具体建造者类:实现创建具体产品各个部件的接口。
二、特点
1、抽象建造者的产品引用以受保护的权限给子类继承。
2、所有产品都具备一样的结构,一个具体产品都有一个具体建造者。
三、目的
将构建过程和表示分离,使得同样的构建过程可以创建不同的表示。
四、缺点
1、灵活性限制问题,指挥者的构建过程固定限制了灵活性。
五、示例代码
javascript
#include<iostream>
#include <vector>
#include <list>
#include <string>
#include <mutex>
#include <map>
#include<stack>
using namespace std;
class Monster;//抽象产品类
class M_Undead;//具体产品类
class M_Element;//具体产品类
class M_Mechanic;//具体产品类
class MonsterBuilder;//抽象建造者类
class MBuilder_Undead;//具体建造者
class MBuilder_Element;//具体建造者
class MBuilder_Mechanic;//具体建造者
class Monster {
public:
virtual ~Monster() {};
virtual void print() = 0;
};
class M_Undead : public Monster {
public:
~M_Undead() {
cout << "~M_Undead" << endl;
};
void print() {
cout << "Undead Monster" << endl;
}
};
class M_Element : public Monster {
public:
~M_Element() {
cout << "~M_Element" << endl;
};
void print() {
cout << "Element Monster" << endl;
}
};
class M_Mechanic : public Monster {
public:
~M_Mechanic() {
cout << "~M_Mechanic" << endl;
};
void print() {
cout << "Mechanic Monster" << endl;
}
};
class MonsterBuilder {
public:
Monster* GetResult() {
return m_monster.get();
}
virtual void loadTrunkModel(string strno) = 0;
virtual void loadHeadModel(string strno) = 0;
virtual void loadLimbsModel(string strno) = 0;
virtual ~MonsterBuilder() {};
protected:
unique_ptr<Monster> m_monster;
};
class MBuilder_Undead : public MonsterBuilder {
public:
MBuilder_Undead() {
m_monster = make_unique<M_Undead>();
}
Monster* GetResult() {
return m_monster.get();
}
void loadTrunkModel(string strno) {
cout << "Undead Monster " << strno << " load trunk model" << endl;
};
void loadHeadModel(string strno) {
cout << "Undead Monster " << strno << " load head model" << endl;
};
void loadLimbsModel(string strno) {
cout << "Undead Monster " << strno << " load limbs model" << endl;
};
~MBuilder_Undead() {
cout << "~MBuilder_Undead" << endl;
};
};
class MBuilder_Element : public MonsterBuilder {
public:
MBuilder_Element() {
m_monster = make_unique<M_Element>();
}
Monster* GetResult() {
return m_monster.get();
}
void loadTrunkModel(string strno) {
cout << "Element Monster " << strno << " load trunk model" << endl;
};
void loadHeadModel(string strno) {
cout << "Element Monster " << strno << " load head model" << endl;
};
void loadLimbsModel(string strno) {
cout << "Element Monster " << strno << " load limbs model" << endl;
};
~MBuilder_Element() {
cout << "~MBuilder_Element" << endl;
};
};
class MBuilder_Mechanic : public MonsterBuilder {
public:
MBuilder_Mechanic() {
m_monster = make_unique<M_Mechanic>();
}
Monster* GetResult() {
return m_monster.get();
}
void loadTrunkModel(string strno) {
cout << "Mechanic Monster " << strno << " load trunk model" << endl;
};
void loadHeadModel(string strno) {
cout << "Mechanic Monster " << strno << " load head model" << endl;
};
void loadLimbsModel(string strno) {
cout << "Mechanic Monster " << strno << " load limbs model" << endl;
};
~MBuilder_Mechanic() {
cout << "~MBuilder_Mechanic" << endl;
};
};
class MonsterDirector {
public:
MonsterDirector(MonsterBuilder* pMonsterBuilder) : m_monsterBuilder(pMonsterBuilder) {}
Monster* Construct(string strModelNo) {
m_monsterBuilder->loadHeadModel(strModelNo);
m_monsterBuilder->loadTrunkModel(strModelNo);
m_monsterBuilder->loadLimbsModel(strModelNo);
return m_monsterBuilder->GetResult();
}
void SetBuilder(MonsterBuilder* pMonsterBuilder) {
m_monsterBuilder = pMonsterBuilder;
}
private:
MonsterBuilder* m_monsterBuilder;
};
int main() {
unique_ptr<MBuilder_Undead> mBuilder_Undead = make_unique<MBuilder_Undead>();
unique_ptr<MBuilder_Element> mBuilder_Element = make_unique<MBuilder_Element>();
unique_ptr<MBuilder_Mechanic> mBuilder_Mechanic = make_unique<MBuilder_Mechanic>();
unique_ptr<MonsterDirector> monsterDirector = make_unique<MonsterDirector>(mBuilder_Undead.get());
Monster* m_undead = monsterDirector->Construct("Undead");
m_undead->print();
monsterDirector->SetBuilder(mBuilder_Element.get());
Monster* m_element = monsterDirector->Construct("Element");
m_element->print();
monsterDirector->SetBuilder(mBuilder_Mechanic.get());
Monster* m_mechanic = monsterDirector->Construct("Mechanic");
m_mechanic->print();
}