//: C10: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_H ///:~
Listado 9.27. C10/Bicycle.h
//: C10:Bicycle.cpp {O} {-mwcc} #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(); } ///:~
Listado 9.28. C10/Bicycle.cpp
//: C10:BuildBicycles.cpp //{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); } /* 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 } */ ///:~
Listado 9.29. C10/BuildBicycles.cpp