- Published on
设计模式(2)——生成器 Builder
- Authors
- Name
- Leon
目录:
二、Builder (生成器模式,对象创建型模式)
1. 问题:
一个对象的创建经过很多步骤,通常由很多其他对象组合而成。
2. 功能:
可以在每一步的构造过程中引入参数,使得经过相同的步骤创建最后得到的对象的展示不一样,即生成器模式暴露出一组标准的构建产品的抽象方法,允许用户参与到构建产品的过程中,以控制产品的生成。
3. 意图:
将一个复杂对象的构建与它的表示分离,使得同样的构建可以创建不同的表示。
4. 类图:
5. Builder 模式与 AbstractFactory 模式的区别:
- 二者功能上很相似,Builder 强调的是一步步创建对象,并通过相同的创建过程可以获得不同的结果对象。而 AbstractFactory 强调的是为创建多个相互依赖的对象提供一个同一的接口。
- 如果一个产品只有一个构造过程,那么生成器模式就退化成了简单工厂模式。
6. C++实现:
- 先写一个 Builder 生成器类
- Builder 类中编写各个构建产品的方法
void BuildPartA(stirng para);...
- 再写一个 Director 导向器类, Director 包含一个 Builder
- 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;
}