中国 - 喜马拉雅

       Let life be beautiful like summer flowers . . .

构建器模式用于创建复杂对象。GoF指出,构建器模式和抽象工厂模式主要的区别就就是,构建器模式一步步创建对象,所以及时展开输出创建过程似乎很重要。此外“主管(BicycleTechnician)”获得一个切片的流(stream),次且将这些切片传递给构建器,每个切片用来执行创建过程中的一步。

下面有一个例子,作为模型的一辆自行车按照其类型(山地车、旅行车或赛车)来选择零部件组装一辆自行车。一个构建器与每个自行车类都关联,每个构建器实现的接口由抽象类BicycleBuilder中指定。单独的类BicycleTechnician表示“四人帮”中描述的“导向器”对象,它使用具体的BicycleBuilder对象来构造Bicycle对象。

Bicycle.h文件:

// 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.cpp文件:

// Bicycle.cpp
#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();
}

main.cpp文件:

#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);
}
 
/* 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 }
*/

这种模式的功能就是它将部件组合为一个完整产品的算法与部件本身分开,这样就充许通过一个共同接口(Bicycle中的纯虚函数)的不同实现(山地车、旅行车和赛车类)来为不同产品提供不同的算法。

选自《C++编程思想》。

posted on 2012-10-02 21:12  chinaxmly  阅读(358)  评论(0编辑  收藏  举报