Builder模式与工厂模式非常相似,但是侧重点不同。Builder多了一个Director类。
工厂模式生产的产品并不注重装配顺序,其侧重点在于创建。
Builder模式的产品必须有固定的装配流程,其侧重点在于流程。
对于某些产品,若装配流程不同,会导致最终的产品不同,那么就需要采用Builder模式。
对于简单产品而言,使用工厂模式非常合适;对于复杂产品而言,Builder模式是非常合适且有效的。
以下的示例代码都省略了构造函数与析构函数。
1. 产品:Product
Builder模式的产品必然是有某个固定装配流程的(注意并非固定部分)。这一点虽然是Product的要求,但是从Product上体现不明显。从Builder上有非常明显的体现。
产品计数器是一种特殊的产品,负责计数工作。
//产品基类
class Product
{
public:
virtual void build(int part, int value) = 0;
protected:
int productValue;
};
//产品A:ProductA
class ProductA : public Product
{
public:
virtual void build(int part, int value)
{
switch (part)
{
case 1:
productValue += value + 1;
break;
case 2:
productValue += value + 10;
break;
case 3:
productValue += value + 100;
break;
default:
break;
}
};
};
//产品B:ProductB
class ProductB : public Product
{
public:
virtual void build(int part, int value)
{
switch (part)
{
case 1:
productValue += value * 1;
break;
case 2:
productValue += value * 10;
break;
case 3:
productValue += value * 100;
break;
default:
break;
}
};
};
//产品计数器:ProductCounter
class ProductCounter : public Product
{
public:
virtual void build(int part, int value)
{
_counter++;
};
int getCounter() { return _counter; };
private:
int _counter;
};
2. Builder
Builder是一个建造器,用于建造产品的各个部分。
这要求每一种产品,必然有固定的建造流程。注意固定建造流程并非固定建造部分。比如某些产品要求只建造part2和part3,而不建造part1。但是建造函数buildPart1()必须调用,这是流程决定的。
特殊地,产品计数器的Builder会建造一个ProductCounter,该产品会对操作进行计数。
class builder
{
public:
virtual void buildPart1() = 0;
virtual void buildPart2() = 0;
virtual void buildPart3() = 0;
};
class builderA : public builder
{
public:
virtual void buildPart1();
virtual void buildPart2();
virtual void buildPart3();
};
class builderB : public builder
{
public:
virtual void buildPart1();
virtual void buildPart2();
virtual void buildPart3();
};
class builderCounter : public builder
{
public:
virtual void buildPart1();
virtual void buildPart2();
virtual void buildPart3();
};
3. Director
Director类负责调用传入的Builder来执行固定流程。
产品的生产流程必须固定,这一点在Director中体现出来。无论哪一种Builder,传入后,必须执行该流程。
class Direct
{
public:
void construct(Builder* b)
{
//实现某种产品的组装
b->buildPart1();
b->buildPart2();
b->buildPart3();
};
};
4. 用户使用
对用户而言,需要做的就是创建某种产品的Builder,以及通用的Director。
然后将Builder传给Director,令Director对Builder进行操作。
最后通过Builder获取产品即可。
void main()
{
Direct direct;
Builder* pBuilder;
//生成ProductA
pBuilder = new BuilderA();
direct.construct(pBuilder);
ProductA productA = *pBuilder->getProduct();
delete pBuilder;
//生成ProductB
pBuilder = new BuilderB();
direct.construct(pBuilder);
BuilderB productB = *pBuilder->getProduct();
delete pBuilder;
//生成ProductCounter
pBuilder = new BuilderCounter();
direct.construct(pBuilder);
ProductCounter productCounter = *pBuilder->getProduct();
int counter = productCounter.getCounter();
delete pBuilder;
}
整个流程如下图所示: