现在的位置: 首页 > 综合 > 正文

【2013.1.18】不要哭,因为你的人生是Hard模式。——Builder

2018年02月19日 ⁄ 综合 ⁄ 共 3541字 ⁄ 字号 评论关闭

// // // // // // // // //

///2013.1.18

// // // // // // // // //

Builder模式,

有这样一个笑话:

Builder Pattern是Create-type Pattern,对不对?

哈哈(原创笑话,转载请说明出处),这次要讲的就是能从名字一眼就能看出来的创建型模式——Builder。

【核心】通过Director类指导Builder接口的不同实现类来分步创建完整的对象Product(可在创建过程中传入不同的参数)

首先来看一下UML图:

如上所示,

上图中最为明显的就是Builder接口(C++为虚基类)中,

不同的创建过程BuildPartA(),BuildPartB(),BuildPartC()了。


具体的实现方法是将一个实现了Builder接口的对象传入Director中(利用构造器或是别的方法),

在Director类中调用Construct方法,

根据传入的Builder的对象,

进行相应的Produce对象的构建过程(例如依次调用上面的BuildPartA.、B、C.)

这个模式稍微有点复杂,

因为与之前的几个模式不同,

它涉及到了四个类的使用:

指导生产的Director,

生产产品的接口(标准)Builder,

实现Builder接口的ConcreteBuilder,

被ConcreteBuilder创建并存放在Director中(或被返回)的Product。

这个模式有一个显著的问题,

就是初学者很容易将它与AbstractFactory搞混。

正如我们所知道的,

AbstractFactory也是根据统一的产品规格(接口)

生产出来不同的产品。

如果不加细分,

它们两个确实是极为相像的。

但是我们要抓住它们各自的特点:

AbstractFactory就像是生产同一产品,不同品牌的工厂的抽象。就像是小米与苹果的区别。

Builder就像是同一品牌同一产品,但生产过程中因参数不同,最终生产出来的质量不同的抽象。就像是发热的小米与不发热的小米的区别。

Builder更为强调的步骤,步骤,步骤。

这一点请大家一定搞清楚,

不然开头处的笑话答案就会是False了,哈哈。

具体代码实例:

【大致思路】

有这样一个产品:由三个步骤完成,在每个步骤投入的时间不同,最终产品的质量将会分为三种:Bad,Normal,High(请参考Product.cpp).

在Director内部聚合Builder接口,并且将实现了Builder的具体实例类ConcreteBuilder传入Director的构造器中。再由Director的Construct方法指导Product的生成。


【注意事项】

1.最后生成的Product并没有被返回(被雪藏在Director内),其实可以将Construct的返回值类型更改为Product* 来返回具体的Product对象。

2.注意由于这里将传入Builder的过程放在了Director构造器中进行,因此一个Director的对象只对应一个具体的Builder。当然可以将此过程放在Director的另一个方法中进行,这样Director就可以根据传入不同的Builder类型,构建不同的品牌,但这样实现的话,Director也是AbstractFactory!!!

Product.h

#ifndef _PRODUCT_H_
#define _PRODUCT_H_

enum WorkTime
{
	tenHours = 10,
	twentyHours= 20,
	thirtyHours = 30
};

class Product
{
public:
	Product(int equality);

private:
	~Product(){}
};

#endif

Product.cpp

#include "Product.h"
#include<iostream>

Product::Product(int equality)
{
	std::cout<<"Equality: "<<equality;
	if(equality <= 50)
		std::cout<<" --Bad"<<std::endl;
	else if(equality <= 70)
		std::cout<<" --Normal"<<std::endl;
	else
		std::cout<<" --High"<<std::endl;
}

Builder.h

#ifndef _BUILDER_H_
#define _BUILDER_H_
#include"Product.h"

class Builder
{
public:
	Builder(){}
	~Builder(){}
	virtual void buildFirstPart(WorkTime e) = 0;
	virtual void buildSecondPart(WorkTime e) = 0;
	virtual void buildThridPart(WorkTime e) = 0;
	virtual Product* getProduct() = 0;

private:
	int totalEquality;
};

class ConcreteBuilder: public Builder
{
public:
	ConcreteBuilder(){totalEquality = 0;}
	void buildFirstPart(WorkTime e);
	void buildSecondPart(WorkTime e);
	void buildThridPart(WorkTime e);
	Product* getProduct();

private:
	int totalEquality;

};

#endif

Builder.cpp

#include"Builder.h"

void ConcreteBuilder::buildFirstPart(WorkTime e)
{
	//Initial equality before build product.
	totalEquality = 0;
	this->totalEquality += e;
}

void ConcreteBuilder::buildSecondPart(WorkTime e)
{
	this->totalEquality += e;
}

void ConcreteBuilder::buildThridPart(WorkTime e)
{
	this->totalEquality += e;
}

Product* ConcreteBuilder::getProduct()
{
	return new Product(totalEquality);
}

Director.h

#ifndef  _DIRECTOR_H_
#define  _DIRECTOR_H_
#include"Builder.h"

class Director
{
public:
	Director(Builder* bdr);
	void Construct(WorkTime worktime_1,WorkTime worktime_2,WorkTime worktime_3);

private:
	Builder* builder;
};

#endif

Director.cpp

#include"Director.h"

Director::Director(Builder* bdr)
{
	this->builder = bdr;
}

void Director::Construct(WorkTime worktime_1,WorkTime worktime_2,WorkTime worktime_3)
{
	builder->buildFirstPart(worktime_1);
	builder->buildSecondPart(worktime_2);
	builder->buildThridPart(worktime_3);
	builder->getProduct();
}

main.cpp

#include"Director.h"

int main()
{
	Director* director = new Director(new ConcreteBuilder());

	//putted 40 hours in total.
	director->Construct(tenHours,tenHours,twentyHours);

	//putted 80 hours in total.
	director->Construct(twentyHours,thirtyHours,thirtyHours);

	return 0;
}

输出结果:

最后要勉励大家一下:

人生就是一个大的Director,

我们每个人的行为就是传入方法中的实参,

经过相同的人生阶段,

在人生的最后一刻我们就会return 自己的结果,

最后是Bad equality,

Normal,还是 Excellent.

都将取决于我们自身。

值此契机,

与君共勉。

抱歉!评论已关闭.