模式定义:
生成器模式是为了解决将一个复杂对象的构建和它的表示分离,使得同样的构建过程可以创建不的表示的问题。对象的构建过程相对稳定。
适用情况:
1、当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
2、当构造过程必须允许被构造的对象有不同的表示时。
生成器模式有点类似于template method,都是某个过程的总体流程固定,具体每一步可变。生成器模式是对象的构建过程相对稳定,template method是算法的整体步骤相对稳定。
生成器模式和工厂模式也非常相似,都是构造对象。生成器模式最主要功能是基本方法的调用顺序安排,也就是这些基本方法已经实现了;而工厂方法则重点是创建,你要什么对象我创造一个对象出来,组装顺序则不是他关心的。
下面代码实现了一个house的创建过程,总共有三个版本,一步步演化抽象。
版本1,house的表示和构造未分离。
#include <string>
#include<iostream>
using namespace std;
class House{
public:
House(bool ifBuildWindow):m_ifBuildWindow(ifBuildWindow){
}
void init(){
buildWall();
buildDoor();
if(ifBuildWindow()){
buildWindow();
}
buildRoof();
}
virtual void showHouse() = 0;
virtual ~House(){};
protected:
virtual void buildDoor() = 0;
virtual void buildWall() = 0;
virtual void buildWindow() = 0;
virtual void buildRoof() = 0;
virtual bool ifBuildWindow() = 0;
string m_window;
string m_door;
string m_roof;
string m_wall;
bool m_ifBuildWindow;
};
class StoneHouse :public House{
public:
StoneHouse(bool ifBuildWindow):House(ifBuildWindow){}
protected:
virtual void buildDoor(){
m_door = "big stone door";
}
virtual void buildWall(){
m_wall = "small stone wall";
}
virtual void buildWindow(){
m_window = "medium stone window";
}
virtual void buildRoof(){
m_roof = "little stone roof";
}
virtual bool ifBuildWindow(){
return m_ifBuildWindow;
}
virtual void showHouse(){
printf(" stone houce door : %s, wall : %s, window : %s, root : %s\n",
m_door.c_str(), m_wall.c_str(), m_window.c_str(), m_roof.c_str());
}
};
class IceHouse :public House{
public:
IceHouse(bool ifBuildWindow):House(ifBuildWindow){}
protected:
virtual void buildDoor(){
m_door = "big ice door";
}
virtual void buildWall(){
m_wall = "small ice wall";
}
virtual void buildWindow(){
m_window = "medium ice window";
}
virtual void buildRoof(){
m_roof = "little ice roof";
}
virtual bool ifBuildWindow(){
return m_ifBuildWindow;
}
virtual void showHouse(){
printf(" ice houce door : %s, wall : %s, window : %s, root : %s\n",
m_door.c_str(), m_wall.c_str(), m_window.c_str(), m_roof.c_str());
}
};
//使用
int main()
{
House * pHouse = new StoneHouse(true);
pHouse->init();
pHouse->showHouse();
House * pHouse1 = new IceHouse(true);
pHouse1->init();
pHouse1->showHouse();
}
版本2,house的表示和构造分离。
#include <string>
#include<iostream>
using namespace std;
class House{
public:
House(bool ifBuildWindow):m_ifBuildWindow(ifBuildWindow){
}
virtual void showHouse() = 0;
virtual ~House(){};
public:
string m_window;
string m_door;
string m_roof;
string m_wall;
bool m_ifBuildWindow;
};
class HouseBuilder{
public:
HouseBuilder(House* pHouse):m_pHouse(pHouse){}
public:
void init(){
buildWall();
buildDoor();
if(ifBuildWindow()){
buildWindow();
}
buildRoof();
}
House * getHouse(){
return m_pHouse;
}
virtual ~HouseBuilder(){}
protected:
virtual void buildDoor() = 0;
virtual void buildWall() = 0;
virtual void buildWindow() = 0;
virtual void buildRoof() = 0;
virtual bool ifBuildWindow() = 0;
House * m_pHouse;
};
class StoneHouse :public House{
public:
StoneHouse(bool ifBuildWindow):House(ifBuildWindow){}
virtual void showHouse(){
printf(" stone house door : %s, wall : %s, window : %s, root : %s\n",
m_door.c_str(), m_wall.c_str(), m_window.c_str(), m_roof.c_str());
}
};
class StoneHouseBuilder :public HouseBuilder{
public:
StoneHouseBuilder(House* pHouse):HouseBuilder(pHouse){}
protected:
virtual void buildDoor(){
m_pHouse->m_door = "stone big door";//这里就不get set
}
virtual void buildWall(){
m_pHouse->m_wall = "stone small wall";
}
virtual void buildWindow(){
m_pHouse->m_window = "stone medium window";
}
virtual void buildRoof(){
m_pHouse->m_roof = "stone little roof";
}
virtual bool ifBuildWindow(){
return m_pHouse->m_ifBuildWindow;
}
};
class IceHouse :public House{
public:
IceHouse(bool ifBuildWindow):House(ifBuildWindow){}
virtual void showHouse(){
printf(" ice houce door : %s, wall : %s, window : %s, root : %s\n",
m_door.c_str(), m_wall.c_str(), m_window.c_str(), m_roof.c_str());
}
};
class IceHouseBuilder :public HouseBuilder{
public:
IceHouseBuilder(House* pHouse):HouseBuilder(pHouse){}
protected:
virtual void buildDoor(){
m_pHouse->m_door = "ice big door";//这里就不get set
}
virtual void buildWall(){
m_pHouse->m_wall = "ice small wall";
}
virtual void buildWindow(){
m_pHouse->m_window = "ice medium window";
}
virtual void buildRoof(){
m_pHouse->m_roof = "ice little roof";
}
virtual bool ifBuildWindow(){
return m_pHouse->m_ifBuildWindow;
}
};
//使用
int main()
{
HouseBuilder * pHouseBuilder = new StoneHouseBuilder(new StoneHouse(true));
pHouseBuilder->init();
House *pHouse = pHouseBuilder->getHouse();
pHouse->showHouse();
}
版本3, 将构建的分步骤和总步骤分离,使得总步骤稳定不变(稳定不变的好处:松耦合,可以增量编译、改动无需重新测试等等)
#include <string>
#include<iostream>
using namespace std;
class House{
public:
House(bool ifBuildWindow):m_ifBuildWindow(ifBuildWindow){
}
virtual void showHouse() = 0;
virtual ~House(){};
public:
string m_window;
string m_door;
string m_roof;
string m_wall;
bool m_ifBuildWindow;
};
class HouseBuilder{
public:
HouseBuilder(House* pHouse):m_pHouse(pHouse){}
House * getHouse(){
return m_pHouse;
}
virtual ~HouseBuilder(){}
virtual void buildDoor() = 0;
virtual void buildWall() = 0;
virtual void buildWindow() = 0;
virtual void buildRoof() = 0;
virtual bool ifBuildWindow() = 0;
House * m_pHouse;
};
class HouseDirector{
public:
HouseDirector(HouseBuilder* pHouseBuilder){
this->pHouseBuilder = pHouseBuilder;
}
House* Construct(){
pHouseBuilder->buildWall();
pHouseBuilder->buildDoor();
if(pHouseBuilder->ifBuildWindow()){
pHouseBuilder->buildWindow();
}
pHouseBuilder->buildRoof();
return pHouseBuilder->getHouse();
}
~HouseDirector(){}
private:
HouseBuilder* pHouseBuilder;
};
/*上面是稳定的,应该单独放在一个或多个文件,这里就不放了*/
class StoneHouse :public House{
public:
StoneHouse(bool ifBuildWindow):House(ifBuildWindow){}
virtual void showHouse(){
printf(" stone houce door : %s, wall : %s, window : %s, root : %s\n",
m_door.c_str(), m_wall.c_str(), m_window.c_str(), m_roof.c_str());
}
};
class StoneHouseBuilder :public HouseBuilder{
public:
StoneHouseBuilder(House* pHouse):HouseBuilder(pHouse){}
protected:
virtual void buildDoor(){
m_pHouse->m_door = "stone big door";//这里就不get set
}
virtual void buildWall(){
m_pHouse->m_wall = "stone small wall";
}
virtual void buildWindow(){
m_pHouse->m_window = "stone medium window";
}
virtual void buildRoof(){
m_pHouse->m_roof = "stone little roof";
}
virtual bool ifBuildWindow(){
return m_pHouse->m_ifBuildWindow;
}
};
class IceHouse :public House{
public:
IceHouse(bool ifBuildWindow):House(ifBuildWindow){}
virtual void showHouse(){
printf(" ice houce door : %s, wall : %s, window : %s, root : %s\n",
m_door.c_str(), m_wall.c_str(), m_window.c_str(), m_roof.c_str());
}
};
class IceHouseBuilder :public HouseBuilder{
public:
IceHouseBuilder(House* pHouse):HouseBuilder(pHouse){}
protected:
virtual void buildDoor(){
m_pHouse->m_door = "ice big door";//这里就不get set
}
virtual void buildWall(){
m_pHouse->m_wall = "ice small wall";
}
virtual void buildWindow(){
m_pHouse->m_window = "ice medium window";
}
virtual void buildRoof(){
m_pHouse->m_roof = "ice little roof";
}
virtual bool ifBuildWindow(){
return m_pHouse->m_ifBuildWindow;
}
};
//使用
int main()
{
HouseBuilder * pHouseBuilder = new StoneHouseBuilder(new StoneHouse(true));
HouseDirector * pHouseDirector = new HouseDirector(pHouseBuilder);
House *pHouse = pHouseDirector->Construct();
pHouse->showHouse();
}