Published on

设计模式(2)——生成器 Builder

Authors
  • avatar
    Name
    Leon
    Twitter

目录:

二、Builder (生成器模式,对象创建型模式)

1. 问题:

  一个对象的创建经过很多步骤,通常由很多其他对象组合而成。

2. 功能:

  可以在每一步的构造过程中引入参数,使得经过相同的步骤创建最后得到的对象的展示不一样,即生成器模式暴露出一组标准的构建产品的抽象方法,允许用户参与到构建产品的过程中,以控制产品的生成。

3. 意图:

  将一个复杂对象的构建与它的表示分离,使得同样的构建可以创建不同的表示。

4. 类图:

5. Builder 模式与 AbstractFactory 模式的区别:

  1. 二者功能上很相似,Builder 强调的是一步步创建对象,并通过相同的创建过程可以获得不同的结果对象。而 AbstractFactory 强调的是为创建多个相互依赖的对象提供一个同一的接口。
  2. 如果一个产品只有一个构造过程,那么生成器模式就退化成了简单工厂模式。

6. C++实现:

  1. 先写一个 Builder 生成器类
  2. Builder 类中编写各个构建产品的方法 void BuildPartA(stirng para);...
  3. 再写一个 Director 导向器类, Director 包含一个 Builder
  4. Builder 类中编写一个总的构建方法 void Construct(); 调用 Builder 中的各个构建方法

Builder.h

Builder.h
// Builder.h
#pragma once

#include <iostream>
#include <string>

using namespace std;

class Product;

class Builder {
public:
	virtual ~Builder();

	virtual void BuildPartA(const string& buildPara) = 0;
	virtual void BuildPartB(const string& buildPara) = 0;
	virtual void BuildPartC(const string& buildPara) = 0;

	virtual Product* GetProduct() = 0;

protected:
	Builder();

private:
};

class ConcreteBuilder :public Builder {
public:
	ConcreteBuilder();
	~ConcreteBuilder();
	void BuildPartA(const string& buildPara);
	void BuildPartB(const string& buildPara);
	void BuildPartC(const string& buildPara);
	Product* GetProduct();

protected:
private:
	Product* _product;

};

Builder.cpp

Builder.cpp
// Builder.cpp
#include "Builder.h"
#include "Product.h"

#include <iostream>

using namespace::std;

Builder::Builder() {}
Builder::~Builder() {}
ConcreteBuilder::ConcreteBuilder() {
	_product = new Product();
}
ConcreteBuilder::~ConcreteBuilder() {}

void ConcreteBuilder::BuildPartA(const string& buildPara) {
	cout << "Step1: Build PartA..." << buildPara << endl;
	_product->ProducePart(buildPara);
}

void ConcreteBuilder::BuildPartB(const string& buildPara) {
	cout << "Step2: Build PartB..." << buildPara << endl;
	_product->ProducePart(buildPara);
}

void ConcreteBuilder::BuildPartC(const string& buildPara) {
	cout << "Step3: Build PartC..." << buildPara << endl;
	_product->ProducePart(buildPara);
}

Product* ConcreteBuilder::GetProduct() {
	return _product;
}

Director.h

Director.h
// Director.h
#pragma once

#include <string>

using namespace::std;

class Builder;
class Director {
public:
	Director(Builder* bld);
	~Director();
	void Construct(string, string, string);
protected:
private:
	Builder* _bld;
};

Director.cpp

Directory.cpp
// Directory.cpp
#include "Director.h"
#include "Builder.h"

Director::Director(Builder* bld){
	_bld = bld;
}
Director::~Director() {}
void Director::Construct(string a, string b, string c) {
	_bld->BuildPartA(a);
	_bld->BuildPartB(b);
	_bld->BuildPartC(c);
}

Product.h

Product.h
// Product.h
#pragma once

#include <string>
using namespace::std;

class Product {
public:
	Product();
	~Product();
	void ProducePart(string part);
	void PrintProduct();
protected:

private:
	string _name = "";
};

Product.cpp

Product.cpp
#include "Product.h"

#include <iostream>

using namespace::std;

Product::Product() {}
Product::~Product() {}

void Product::ProducePart(string part){
	cout << part;
	_name += part;
}

void Product::PrintProduct() {
	cout << "The builded product is: \n" << _name << endl;
}

main.cpp

main.cpp
// main.cpp
#include "Builder.h"
#include "Product.h"
#include "Director.h"
#include <iostream>

using namespace::std;

int main(int argc, char* argv[]) {
	Builder* b = new ConcreteBuilder();
	Director* d = new Director(b);

	d->Construct("Hello ", "C++ ", "Language");

	Product* product = b->GetProduct();

	product->PrintProduct();

	return 0;
}