Builder模式的使用场合
(1)相同的方法,不同的执行顺序,产生不同的事件结构时,可以采用建造者模式。
(2)多个部件或零件,都可以装配到一个对象中,但是产生的运行结果又不相同时,则可以使用该模式。
(3)产品类非常复杂,或者产品类中的调用顺序不同产生了不同的效能,这个可以使用该模式。
【编程实验】将数据导出为txt和xml格式的文件
①文件头:包括部门ID、导出数据的日期
②文件体:表名称、分条描述数据
③文件尾:输出人的信息
//声明文件
//*********************************************************************************
//创建型模式:建造者模式
//将数据导出为不同格式的文件
#include <iostream>
#include <string>
#include <sstream>
#include <list>
using namespace std;
//*************************辅助类:各个部件************************
//文件头对象
class CFileHeader{
private:
string strDeptNo;//部门编号
string strExpDate; //导出数据的日期
public:
void SetDeptNo(string dept);
string GetDeptNo();
void SetExpDate(string date);
string GetExpDate();
};
//文件体
class CFileBody{
private:
string strProduct; //产品编号
double dPrice; //销售价格
long lAmount;//销售数量
public:
void SetProduct(string product);
string GetProduct();
void SetPrice(double price);
double GetPrice();
void SetAmount(long amount);
long GetAmount();
};
//文件尾
class CFileFooter{
private:
string strUser;//输出人
public:
void SetUser(string user);
string GetUser();
};
//*******************************Builder*************************
class CFileBuilder{
public:
virtual void BuildHeader(CFileHeader& header) = 0;
virtual void BuildBody(list<CFileBody>& bodys) = 0;
virtual void BuildFooter(CFileFooter& footer) = 0;
virtual string& Output() = 0;
};
//XmlBuilder
class CXmlBuilder : public CFileBuilder{
private:
string strBuff;//用来记录文件的内容,相当于最终产品
public:
void BuildHeader(CFileHeader& header);
void BuildBody(list<CFileBody>& bodys);
void BuildFooter(CFileFooter& footer);
string& Output();
};
//TxtBuilder
class CTxtBuilder : public CFileBuilder{
private:
string strBuff;//用来记录文件的内容,相当于最终产品
public:
void BuildHeader(CFileHeader& header);
void BuildBody(list<CFileBody>& bodys);
void BuildFooter(CFileFooter& footer);
string& Output();
};
//*********************************Director*********************
class CFileDirector{
private:
CFileBuilder* pBuilder;
public:
CFileDirector();
CFileDirector(CFileBuilder* builder);
void SelectBuilder(CFileBuilder* builder);
void Construct(CFileHeader& header, list<CFileBody>& bodys, CFileFooter& footer);
};
//实现文件
//*********************************************************************************
//创建型模式:建造者模式
//将数据导出为不同格式的文件
//*************************辅助类:各个部件************************
//文件头对象
void CFileHeader::SetDeptNo(string dept){strDeptNo = dept;}
string CFileHeader::GetDeptNo(){return strDeptNo;}
void CFileHeader::SetExpDate(string date){strExpDate = date;}
string CFileHeader::GetExpDate(){return strExpDate;}
//文件体
void CFileBody::SetProduct(string product){strProduct = product;}
string CFileBody::GetProduct(){return strProduct;}
void CFileBody::SetPrice(double price){dPrice = price;}
double CFileBody::GetPrice(){return dPrice;}
void CFileBody::SetAmount(long amount){lAmount = amount;}
long CFileBody::GetAmount(){return lAmount;}
//文件尾
void CFileFooter::SetUser(string user){strUser = user;}
string CFileFooter::GetUser(){return strUser;}
//*******************************Builder*************************
//XmlBuilder
void CXmlBuilder::BuildHeader(CFileHeader& header)
{
strBuff.append("<?xml version = '1.0' encoding = 'gb2313'?>\n");
strBuff.append("<Report>\n");
strBuff.append(" <Header>\n");
strBuff.append(" <DeptNo>" + header.GetDeptNo() + "</DeptNo>\n");
strBuff.append(" <ExpDate>" + header.GetExpDate() + "</ExpDate>\n");
strBuff.append(" </Header>\n");
}
void CXmlBuilder::BuildBody(list<CFileBody>& bodys)
{
strBuff.append(" <Body>\n");
strBuff.append(" <Datas TableName = Sale Details:>\n");
ostringstream oss;
for(list<CFileBody>::iterator it = bodys.begin(); it != bodys.end(); it++){// list<Body>::iterator
oss.str(""); oss << it->GetPrice();
strBuff.append(" <Data>\n");
strBuff.append(" <ProductId>" + it->GetProduct() + "</ProductId>\n");
strBuff.append(" <Price>" + oss.str() + "</Price>\n");
oss.str(""); oss << it->GetAmount();
strBuff.append(" <Amount>" + oss.str() + "</Amount>\n");
strBuff.append(" <\Data>\n");
}
strBuff.append(" <\Datas\n");
strBuff.append(" <\Body>\n");
}
void CXmlBuilder::BuildFooter(CFileFooter& footer)
{
strBuff.append(" <Footer>\n");
strBuff.append(" <ExpUser>" + footer.GetUser() + "<\ExpUser>\n");
strBuff.append(" </Footer>\n");
strBuff.append("</Report>\n");
}
string& CXmlBuilder::Output(){return strBuff;}
//TxtBuilder
void CTxtBuilder::BuildHeader(CFileHeader& header)
{
strBuff.append(header.GetDeptNo() + ", " + header.GetDeptNo());
}
void CTxtBuilder::BuildBody(list<CFileBody>& bodys)
{
strBuff.append("Sale details:\n");
ostringstream oss;
for(list<CFileBody>::iterator it = bodys.begin(); it != bodys.end(); it++){
strBuff.append("ProductId=" + it->GetProduct() + ", ");
oss.str(""); oss << it->GetPrice();
strBuff.append("Price=" + oss.str() + ", ");
oss.str(""); oss << it->GetAmount();
strBuff.append("Amount=" + oss.str() +". \n");
}
}
void CTxtBuilder::BuildFooter(CFileFooter& footer)
{
strBuff.append(footer.GetUser() + "\n");
}
string& CTxtBuilder::Output(){return strBuff;}
//*********************************Director*********************
CFileDirector::CFileDirector() : pBuilder(NULL){}
CFileDirector::CFileDirector(CFileBuilder* builder) : pBuilder(builder){}
void CFileDirector::SelectBuilder(CFileBuilder* builder) { pBuilder = builder;}
void CFileDirector::Construct(CFileHeader& header, list<CFileBody>& bodys, CFileFooter& footer)
{
pBuilder->BuildHeader(header);
pBuilder->BuildBody(bodys);
pBuilder->BuildFooter(footer);
}
//测试客户端
void main()
{
CFileHeader header; header.SetDeptNo("Kanq"); header.SetExpDate("2018-03-21");
list<CFileBody> bodys;
CFileBody Body1; Body1.SetProduct("001"); Body1.SetPrice(99); Body1.SetAmount(99); bodys.push_back(Body1);
CFileBody Body2; Body2.SetProduct("002"); Body2.SetPrice(55); Body2.SetAmount(49); bodys.push_back(Body2);
CFileFooter footer; footer.SetUser("YuLiangyong");
//创建指导者对象
CFileDirector* pFileDirector = new CFileDirector();
CFileBuilder* pTxtBuilder = new CTxtBuilder(); //测试输出到文本文件
CFileBuilder* pXmlBuilder = new CXmlBuilder(); //测试输出到XML文件
pFileDirector->SelectBuilder(pTxtBuilder);
pFileDirector->Construct(header, bodys, footer);
cout << pTxtBuilder->Output() << endl;
pFileDirector->SelectBuilder(pXmlBuilder);
pFileDirector->Construct(header, bodys, footer);
cout << pXmlBuilder->Output() << endl;
delete pTxtBuilder;
delete pXmlBuilder;
delete pFileDirector;
}