构建器 Builder 模式的模板是将对象的创建与它的 表示法 分开
意味着 创建保持原状
但是产生对象 的表示法 不同
作为模型的自行车按照其内心来选择零部件组装一辆自行车
一个构建器与每个自行车类都关联
每个构建器实现的接口由抽象类BicycleBuilder中指定
//: C10:Bicycle.h
// From "Thinking in C++, Volume 2", by Bruce Eckel & Chuck Allison.
// (c) 1995-2004 MindView, Inc. All Rights Reserved.
// See source code use permissions stated in the file 'License.txt',
// distributed with the code package available at www.MindView.net.
// Defines classes to build bicycles;
// Illustrates the Builder design pattern.
#ifndef BICYCLE_H
#define BICYCLE_H
#include <iostream>
#include <string>
#include <vector>
#include <cstddef>
#include "../purge.h"
using std::size_t;
class BicyclePart {
public:
enum BPart { FRAME, WHEEL, SEAT, DERAILLEUR,
HANDLEBAR, SPROCKET, RACK, SHOCK, NPARTS };
private:
BPart id;
static std::string names[NPARTS];
public:
BicyclePart(BPart bp) { id = bp; }
friend std::ostream&
operator<<(std::ostream& os, const BicyclePart& bp) {
return os << bp.names[bp.id];
}
};
class Bicycle {
std::vector<BicyclePart*> parts;
public:
~Bicycle() { purge(parts); }
void addPart(BicyclePart* bp) { parts.push_back(bp); }
friend std::ostream&
operator<<(std::ostream& os, const Bicycle& b) {
os << "{ ";
for(size_t i = 0; i < b.parts.size(); ++i)
os << *b.parts[i] << ' ';
return os << '}';
}
};
class BicycleBuilder {
protected:
Bicycle* product;
public:
BicycleBuilder() { product = 0; }
void createProduct() { product = new Bicycle; }
virtual void buildFrame() = 0;
virtual void buildWheel() = 0;
virtual void buildSeat() = 0;
virtual void buildDerailleur() = 0;
virtual void buildHandlebar() = 0;
virtual void buildSprocket() = 0;
virtual void buildRack() = 0;
virtual void buildShock() = 0;
virtual std::string getBikeName() const = 0;
Bicycle* getProduct() {
Bicycle* temp = product;
product = 0; // Relinquish product
return temp;
}
};
class MountainBikeBuilder : public BicycleBuilder {
public:
void buildFrame();
void buildWheel();
void buildSeat();
void buildDerailleur();
void buildHandlebar();
void buildSprocket();
void buildRack();
void buildShock();
std::string getBikeName() const { return "MountainBike";}
};
class TouringBikeBuilder : public BicycleBuilder {
public:
void buildFrame();
void buildWheel();
void buildSeat();
void buildDerailleur();
void buildHandlebar();
void buildSprocket();
void buildRack();
void buildShock();
std::string getBikeName() const { return "TouringBike"; }
};
class RacingBikeBuilder : public BicycleBuilder {
public:
void buildFrame();
void buildWheel();
void buildSeat();
void buildDerailleur();
void buildHandlebar();
void buildSprocket();
void buildRack();
void buildShock();
std::string getBikeName() const { return "RacingBike"; }
};
class BicycleTechnician {
BicycleBuilder* builder;
public:
BicycleTechnician() { builder = 0; }
void setBuilder(BicycleBuilder* b) { builder = b; }
void construct();
};
#endif // BICYCLE_H ///:~
Bicycle持有一个vector
用于保存指向BicyclePart对象的指针
对象用于构造自行车的部件具体构建器类省略了与他们所构建的自行车的类型无关的动作
//: C10:Bicycle.cpp {O} {-mwcc}
// From "Thinking in C++, Volume 2", by Bruce Eckel & Chuck Allison.
// (c) 1995-2004 MindView, Inc. All Rights Reserved.
// See source code use permissions stated in the file 'License.txt',
// distributed with the code package available at www.MindView.net.
#include "Bicycle.h"
#include <cassert>
#include <cstddef>
using namespace std;
std::string BicyclePart::names[NPARTS] = {
"Frame", "Wheel", "Seat", "Derailleur",
"Handlebar", "Sprocket", "Rack", "Shock" };
// MountainBikeBuilder implementation
void MountainBikeBuilder::buildFrame() {
product->addPart(new BicyclePart(BicyclePart::FRAME));
}
void MountainBikeBuilder::buildWheel() {
product->addPart(new BicyclePart(BicyclePart::WHEEL));
}
void MountainBikeBuilder::buildSeat() {
product->addPart(new BicyclePart(BicyclePart::SEAT));
}
void MountainBikeBuilder::buildDerailleur() {
product->addPart(
new BicyclePart(BicyclePart::DERAILLEUR));
}
void MountainBikeBuilder::buildHandlebar() {
product->addPart(
new BicyclePart(BicyclePart::HANDLEBAR));
}
void MountainBikeBuilder::buildSprocket() {
product->addPart(new BicyclePart(BicyclePart::SPROCKET));
}
void MountainBikeBuilder::buildRack() {}
void MountainBikeBuilder::buildShock() {
product->addPart(new BicyclePart(BicyclePart::SHOCK));
}
// TouringBikeBuilder implementation
void TouringBikeBuilder::buildFrame() {
product->addPart(new BicyclePart(BicyclePart::FRAME));
}
void TouringBikeBuilder::buildWheel() {
product->addPart(new BicyclePart(BicyclePart::WHEEL));
}
void TouringBikeBuilder::buildSeat() {
product->addPart(new BicyclePart(BicyclePart::SEAT));
}
void TouringBikeBuilder::buildDerailleur() {
product->addPart(
new BicyclePart(BicyclePart::DERAILLEUR));
}
void TouringBikeBuilder::buildHandlebar() {
product->addPart(
new BicyclePart(BicyclePart::HANDLEBAR));
}
void TouringBikeBuilder::buildSprocket() {
product->addPart(new BicyclePart(BicyclePart::SPROCKET));
}
void TouringBikeBuilder::buildRack() {
product->addPart(new BicyclePart(BicyclePart::RACK));
}
void TouringBikeBuilder::buildShock() {}
// RacingBikeBuilder implementation
void RacingBikeBuilder::buildFrame() {
product->addPart(new BicyclePart(BicyclePart::FRAME));
}
void RacingBikeBuilder::buildWheel() {
product->addPart(new BicyclePart(BicyclePart::WHEEL));
}
void RacingBikeBuilder::buildSeat() {
product->addPart(new BicyclePart(BicyclePart::SEAT));
}
void RacingBikeBuilder::buildDerailleur() {}
void RacingBikeBuilder::buildHandlebar() {
product->addPart(
new BicyclePart(BicyclePart::HANDLEBAR));
}
void RacingBikeBuilder::buildSprocket() {
product->addPart(new BicyclePart(BicyclePart::SPROCKET));
}
void RacingBikeBuilder::buildRack() {}
void RacingBikeBuilder::buildShock() {}
// BicycleTechnician implementation
void BicycleTechnician::construct() {
assert(builder);
builder->createProduct();
builder->buildFrame();
builder->buildWheel();
builder->buildSeat();
builder->buildDerailleur();
builder->buildHandlebar();
builder->buildSprocket();
builder->buildRack();
builder->buildShock();
getchar();
} ///:~
Bicycle流插入符为各个BicyclePart调用相应的插入符
并且打印器类型名称以便知道Bicycle对象包含的内容
//: C10:BuildBicycles.cpp
// From "Thinking in C++, Volume 2", by Bruce Eckel & Chuck Allison.
// (c) 1995-2004 MindView, Inc. All Rights Reserved.
// See source code use permissions stated in the file 'License.txt',
// distributed with the code package available at www.MindView.net.
//{L} Bicycle
// The Builder design pattern.
#include <cstddef>
#include <iostream>
#include <map>
#include <vector>
#include "Bicycle.h"
#include "../purge.h"
using namespace std;
// Constructs a bike via a concrete builder
Bicycle* buildMeABike(
BicycleTechnician& t, BicycleBuilder* builder) {
t.setBuilder(builder);
t.construct();
Bicycle* b = builder->getProduct();
cout << "Built a " << builder->getBikeName() << endl;
return b;
}
int main() {
// Create an order for some bicycles
map <string, size_t> order;
order["mountain"] = 2;
order["touring"] = 1;
order["racing"] = 3;
// Build bikes
vector<Bicycle*> bikes;
BicycleBuilder* m = new MountainBikeBuilder;
BicycleBuilder* t = new TouringBikeBuilder;
BicycleBuilder* r = new RacingBikeBuilder;
BicycleTechnician tech;
map<string, size_t>::iterator it = order.begin();
while(it != order.end()) {
BicycleBuilder* builder;
if(it->first == "mountain")
builder = m;
else if(it->first == "touring")
builder = t;
else if(it->first == "racing")
builder = r;
for(size_t i = 0; i < it->second; ++i)
bikes.push_back(buildMeABike(tech, builder));
++it;
}
delete m;
delete t;
delete r;
// Display inventory
for(size_t i = 0; i < bikes.size(); ++i)
cout << "Bicycle: " << *bikes[i] << endl;
purge(bikes);
getchar();
}
/* Output:
Built a MountainBike
Built a MountainBike
Built a RacingBike
Built a RacingBike
Built a RacingBike
Built a TouringBike
Bicycle: {
Frame Wheel Seat Derailleur Handlebar Sprocket Shock }
Bicycle: {
Frame Wheel Seat Derailleur Handlebar Sprocket Shock }
Bicycle: { Frame Wheel Seat Handlebar Sprocket }
Bicycle: { Frame Wheel Seat Handlebar Sprocket }
Bicycle: { Frame Wheel Seat Handlebar Sprocket }
Bicycle: {
Frame Wheel Seat Derailleur Handlebar Sprocket Rack }
*/ ///:~
输出
Built a MountainBike
Built a MountainBike
Built a RacingBike
Built a RacingBike
Built a RacingBike
Built a TouringBike
Bicycle: { Frame Wheel Seat Derailleur Handlebar Sprocket Shock }
Bicycle: { Frame Wheel Seat Derailleur Handlebar Sprocket Shock }
Bicycle: { Frame Wheel Seat Handlebar Sprocket }
Bicycle: { Frame Wheel Seat Handlebar Sprocket }
Bicycle: { Frame Wheel Seat Handlebar Sprocket }
Bicycle: { Frame Wheel Seat Derailleur Handlebar Sprocket Rack }
这种模式的功能就是它将部件组合成为一个完整产品算法与部件本身分开
这样就允许通过一个共同接口的不同实现来为不同的产品提供不同的算法