目录
背景:
软件构建过程中有时候一个复杂的对象的构建可分解为多个子对象按照一定的算法逻辑进行构建,这种构建算法基本稳定但构建的子部件却经常变化。
创建者模式则是将构建的算法和子组件分开,将变化和不变分开,当子组件变化时只影响子组件本身不影响构建算法本身,加强了构建算法的封闭性,提升了组件的扩展性。
构建模式UML
这里以建房子为例,房子构建过程抽象为地基、墙体、屋顶和装修等4个部分。四个部分构建流程基本不变,但是四个部分所用的材料和组合等均可以变化,根据构建模式其UML图如下。
代码示例
房子成品:
这里简化为四部分。
cpp
struct House
{
std::string HouseBase;
std::string HouseWall;
std::string HouseTop;
std::string HouseDecorator;
};
构建器抽象:
cpp
class HouseBuilder
{
public:
House*getHousr()
{
return m_house;
}
HouseBuilder(){
m_house = new House();
}
~HouseBuilder()
{
if (m_house)
{
delete m_house;
}
}
virtual void buildPart1() = 0;
virtual void buildPart2() = 0;
virtual void buildPart3() = 0;
virtual void buildPart4() = 0;
protected:
House* m_house = nullptr;
};
具体构建器:
经常变化的构建,不同的房子需要不同的构建器,一套房子对应一种构建器;若有新品房子则需要重写构建器,增量开发不影响原本的构建器和建筑师建筑流程。
cpp
class StoneHouseBuilder :public HouseBuilder
{
public:
void buildPart1() override { std::cout << "打水泥地基" << std::endl; m_house->HouseBase = "石头地基"; }
void buildPart2() override { std::cout << "砌石头墙" << std::endl; m_house->HouseWall = "石头墙"; }
void buildPart3() override { std::cout << "盖琉璃屋顶" << std::endl; m_house->HouseTop = "琉璃顶"; }
void buildPart4() override { std::cout << "石灰滚刷装修,铺地装" << std::endl; m_house->HouseDecorator = "石灰滚刷装修,铺地装"; }
};
class GrassHouseBuilder :public HouseBuilder
{
public:
void buildPart1() override { std::cout << "木桩打地基" << std::endl;m_house->HouseBase = "木桩地基"; }
void buildPart2() override { std::cout << "竹子编制墙" << std::endl; m_house->HouseWall = "竹子墙"; }
void buildPart3() override { std::cout << "茅草盖屋顶" << std::endl; m_house->HouseTop = "茅草顶"; }
void buildPart4() override { std::cout << "茅草遮墙做防风" << std::endl; m_house->HouseDecorator = "茅草遮墙做防风"; }
};
建筑师:
建筑流程稳定,基本不变;根据使用不同的构建器可得到不同房子的建筑师,建出不同的房子。
cpp
class HouseDirector
{
public:
HouseBuilder*pHouserBuilder = nullptr;
HouseDirector(HouseBuilder*pHB) :pHouserBuilder(pHB) {
}
House* Construct() {
//构建过程稳定不变 但是构建的各个组件部分剧烈变动
pHouserBuilder->buildPart1();
pHouserBuilder->buildPart2();
pHouserBuilder->buildPart3();
pHouserBuilder->buildPart4();
return pHouserBuilder->getHousr();
}
};
测试部分:
cpp
void TestFun::TestBuilder()
{
StoneHouseBuilder builder1;
HouseDirector stone_Director(&builder1);
House* pStoneHouse = stone_Director.Construct();
GrassHouseBuilder builder2;
HouseDirector grass_Director(&builder2);
House* pgrassHouse = grass_Director.Construct();
}