说下对建造者模式的理解:
建造者模式:将一个复杂的对象的构建与他的表示分离, 使得同样的构建过程可以创建不同的表示。
它使用builder 构建各个部分的抽象接口, 由子类具体实现。 通过director 指挥构建的过程, 这个构建的过程一般是相对比较固定的。
他主要用来创建一些比较复杂的对象,并且这些对象之间的建造顺序通常是稳定的, 但对象内部的构建通常面临比较复杂的变化。
他使得建造代码和表示代码分离, 隐藏了产品组装的方式, 如果需要改变一个产品的内部表示, 只需要在定义一个具体的建造者就可以了。
个人感觉, 他和外观模式有一定的相似性, 或者说, 感觉很像,外观模式, 是为一组复杂的类提供一组统一的访问方式, 符合迪米特原则和依赖倒转原则。 而这里的建造者模式, 感觉也是有一堆构建部件的子类, 通过director这个构建者, 实现组装的, 用户不用再关注部件构造这些复杂的过程。
通常建造者模式的builder定义一组抽象接口, 由子类去具体实现, 在我们这个例子中, 为避免代码复杂化, 我们进行了改造, 融入了模板模式的思想, 将一部分公共元素,提取到基类,子类只要实现部分差异表现即可。
下面是UML图:
运行效果图:
下面是代码部分:
product.h
#ifndef _PRODUCT_H_
#define _PRODUCT_H_
#include <string>
#include <iostream>
using std::cout;
using std::endl;
using std::string;
/************************************************************************/
/* 产品类, 建造者模式最终生成的对象 */
/************************************************************************/
class CProduct{
public:
string Description() const { return description; }
void Description(string val) { description = val; }
void display(){ cout << Description() << endl; }
private:
string description;
};
#endif // _PRODUCT_H_
productbuilder.h
#ifndef _PERSONBUILDER_H_
#define _PERSONBUILDER_H_
#include "product.h"
#include <string>
#include <memory>
using std::string;
using std::shared_ptr;
/************************************************************************/
/* 建造者的细节接口 + 模板模式 */
/************************************************************************/
class CPersonBuilder{
public:
CPersonBuilder() : product(new CProduct){}
/************************************************************************/
/* 建造的主体部件, 模板 */
/************************************************************************/
void BuildHead();
void BuildBody();
void BuildArmLeft();
void BuildArmRight();
void BuildLegLeft();
void BuildLegRight();
// display
shared_ptr<CProduct> getResult() const { return product; }
private:
/************************************************************************/
/* 具体实现的接口 */
/************************************************************************/
virtual string head() = 0;
virtual string body() = 0;
virtual string armleft() = 0;
virtual string armright() = 0;
virtual string legleft() = 0;
virtual string legright() = 0;
private:
shared_ptr<CProduct> product;
};
/************************************************************************/
/* 具体的建造方式 thin */
/************************************************************************/
class CPersonThinBuilder : public CPersonBuilder{
private:
string head(){ return "head\t"; }
string body(){ return "thin body\t"; }
string armleft(){ return "arm left\t"; }
string armright(){ return "arm right\t"; }
string legleft(){ return "leg left\t"; }
string legright(){ return "leg right\t"; }
};
/************************************************************************/
/* 具体的建造方式 fat */
/************************************************************************/
class CPersonFatBuilder : public CPersonBuilder{
private:
string head(){ return "head\t"; }
string body(){ return "fat body\t"; }
string armleft(){ return "arm left\t"; }
string armright(){ return "arm right\t"; }
string legleft(){ return "leg left\t"; }
string legright(){ return "leg right\t"; }
};
#endif // _PERSONBUILDER_H_
productbuilder.cpp
#include "personbuilder.h"
/************************************************************************/
/* CPersonBuilder 的基本构架 */
/************************************************************************/
void CPersonBuilder::BuildHead()
{
string tmp = product->Description();
product->Description(tmp + head());
}
void CPersonBuilder::BuildBody()
{
string tmp = product->Description();
product->Description(tmp + body());
}
void CPersonBuilder::BuildArmLeft()
{
string tmp = product->Description();
product->Description(tmp + armleft());
}
void CPersonBuilder::BuildArmRight()
{
string tmp = product->Description();
product->Description(tmp + armright());
}
void CPersonBuilder::BuildLegLeft()
{
string tmp = product->Description();
product->Description(tmp + legleft());
}
void CPersonBuilder::BuildLegRight()
{
string tmp = product->Description();
product->Description(tmp + legright());
}
persondirector.h
#include "personbuilder.h"
#include <memory>
using std::shared_ptr;
class CPersonDirector{
public:
//************************************
// Method: CreateThinPerson
// FullName: CPersonDirector::CreateThinPerson
// Access: public
// Returns:
// Qualifier: 创建一个 ThinPerson 对象
//************************************
void CreatePerson(CPersonBuilder * builder){
builder->BuildHead();
builder->BuildBody();
builder->BuildArmLeft();
builder->BuildArmRight();
builder->BuildLegLeft();
builder->BuildLegRight();
}
};
#endif // _PERSONDIRECTOR_H_
main.cpp
#include "persondirector.h"
#include <iostream>
#include <memory>
using namespace std;
int main(){
shared_ptr<CPersonBuilder> builderFat(new CPersonFatBuilder);
shared_ptr<CPersonBuilder> builderThin(new CPersonThinBuilder);
CPersonDirector director;
director.CreatePerson(builderFat.get());
shared_ptr<CProduct> product = builderFat->getResult();
product->display();
// product = builderThin->getResult();
// product->display();
director.CreatePerson(builderThin.get());
product = builderThin->getResult();
product->display();
system("pause");
return 0;
}