builder模式:对象创建型模式
意图:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
适用性:
1 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
2 当构造过程必须允许被构造的对象有不同的表示时
结构图:
参与者:
Builder: 为创建一个Product对象的各个部件指定抽象接口
ConcreteBuilder:实现Builder 的接口以构造和装配该产品的各个部件;定义并明确它所创建的表示;踢狗一个使用Builder接口的对象
Director:构造一个使用Builder接口的对象
Product:表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程;包含定义组成部件的类,包括将这些部件装配程最终产品的接口。
协作:
客户创建Director对象,并用它所想要的Builder对象进行配置
一旦产品部件被生成,导向就会通知生成器
生成器处理导向器的请求,并将部件添加到该产品中
客户从生成器中检索产品
如下图:
效果:
1 可以改变一个产品的内部表示,Builder只提供给导向器接口,隐藏了产品的内部表示和结构,同时也隐藏了产品是如何装配的
2 将构造代码和表示代码分开
3 使你可以对构造过程进行更精细的控制
以下为模式实现代码:
//builder模式:将一个复杂对象的构建与它的表示分离,
//使得同样的构建过程可以创建不同的表示
#include <iostream>
#include <string>
#include <list>
using namespace std;
//产品类,由多个部件组成
class Product
{
public:
//添加产品部件
void Add(string part)
{
parts.push_back(part);
}
void show()
{
cout << "产品创建------" << endl;
int cnt = 0;
for (list<string>::iterator it = parts.begin();
it != parts.end(); it++)
{
cout << "创建第 " << ++cnt << " 个部件: " << *it << endl;
}
}
private:
list<string> parts;
};
//Builder类,抽象建造者类,确定产品由两个部件PartA和PartB组成
//并声明一个得到产品建筑后结果的方法GetResult
class Builder
{
public:
//定义成空方法,可以使派生类只重新定义成感兴趣的方法。
//如果为纯虚函数,则都得定义
virtual void BuildPartA() {}
virtual void BuildPartB() {}
virtual Product& GetResult() {}
};
//ConcreteBuilder1:具体建造者类
class ConcreteBuilder1 : public Builder
{
public:
void BuildPartA()
{
pro.Add("部件A");
}
void BuildPartB()
{
pro.Add("部件B");
}
Product& GetResult()
{
return pro;
}
private:
Product pro;
};
//ConcreteBuilder2:具体建造者类
class ConcreteBuilder2 : public Builder
{
public:
void BuildPartA()
{
pro.Add("部件X");
}
void BuildPartB()
{
pro.Add("部件Y");
}
Product& GetResult()
{
return pro;
}
private:
Product pro;
};
//指挥者类:构造一个使用builder接口的对象
class Director
{
public:
void Construct(Builder& builder)
{
builder.BuildPartA();
builder.BuildPartB();
}
};
int main()
{
//定义一个指挥者,指挥者指挥是创建哪个具体的对象
Director *director = new Director;
Builder *b1 = new ConcreteBuilder1;
Builder *b2 = new ConcreteBuilder2;
director->Construct(*b1);
Product p1 = b1->GetResult();
p1.show();
director->Construct(*b2);
Product p2 = b2->GetResult();
p2.show();
system("pause");
return 0;
}