最近在看设计模式,看到了建造者模式(Builder),这是我的第一篇设计模式博客文章,之前看过一些经典模式,没有记录下来,以后会相应的将补充一些博文。我们直接进入正题。
我想,关于建造者模式的书面定义,大家在不同的书本中肯定会得到标准的官方定义,借用程杰老师的《大话设计模式》当中的定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。Oh,我的天,我想大家第一次看到这种定义已经会疯掉的,到底这句话表示什么意思啊,让我们来分析分析。
1、复杂对象:通俗的说,就是一个对象的各个部分由一定的算法构成,这些算法的实现方式不相同。这些实现方式会随着外部因素的不同而发生剧烈的变化,也就是说,对象的构造很复杂,要应对客户端的不同变化。
2、表示:说白了就是对象的实现啦。我们可以从概念中理解到,表示(实现)是多样的。
3、对象的构建:就是将一个对象的各个子部分结合起来的过程。对象子部分的实现各有不同,但是其构建顺序却相对稳定。
下面我们根据我们上面三点分析,举个简单的例子来说明一下。
比如,我们要画一人,第一,从常识我们知道,人由头,手,脚,躯干组成,我们画一个人的时候,这四个部分是必须的(总不能画个残疾人出来吧,呵呵),这就是人(对象)的构建;第二,人也是不同的嘛,有高矮胖瘦之分,所以画人的时候,组成人的四个部分的长短大小因人而异,这就是概念中说的不同的表示(实现)。好了,我们通俗的理解了一下构造模式的概念,下面我们来真正的剖析一下建造者模式:
类图:
直接从网上搞了一张图,谢谢画图的博主。
导演类Director:直接和客户端打交道的类,首先其有有一个函数Construct,调用ConcreteBuilder类的函数来构造产品,所以Construct函数要传入一个Builder对象。
建造者类Builder:所以具体生成产品的基类,该类封装了组成(构建)产品的标准流程,子类继承它后,就不会构造残缺的对象了(意思就是不会产生有残疾的人)。
具体建造者类ConcreteBuilder:具体承担产生产品的类
产品类Porduct:产品类。由多个部件组成
好了,下面用代码来具体实现以下建造者模式(C++):
class Productor
{
std::vector<std::string> m_Parts;
public:
void Add(std::string part)
{
m_Parts.push_back(part);
}
void Show()
{
std::cout<<"产品创建------"<<std::endl;
for(int i = 0; i != m_Parts.size(); ++i)
{
std::cout<<m_Parts.at(i);
}
}
};
class Builder
{
public:
virtual void BuildPartA();
virtual void BuildPartB();
virtual Productor GetResult();
};
class ConcreteBuilder1:public Builder
{
Productor m_Productor;
public:
void BuildPartA()
{
m_Productor.Add("部件A");
}
void BuildPartB()
{
m_Productor.Add("部件B");
}
Productor GetResult()
{
return m_Productor;
}
};
class ConcreteBuilder2:public Builder
{
Productor m_Productor;
public:
void BuildPartA()
{
m_Productor.Add("部件X");
}
void BuildPartB()
{
m_Productor.Add("部件Y");
}
Productor GetResult()
{
return m_Productor;
}
};
class Director
{
public:
void Constrcut(Builder vBuilder)
{
vBuilder.BuildPartA();
vBuilder.BuildPartB();
}
};
int main()
{
Director director = new Director();
Builder b1 = new ConcreteBuilder1();
Builder b2 = new ConcreteBuilder2();
director.Constrcut(b1);
Productor d1 = b1.GetResult();
d1.Show();
director.Constrcut(b2);
Productor d2 = b2.GetResult();
d2.Show();
return 0;
}