Skip to content

Instantly share code, notes, and snippets.

@pazdera
Created August 2, 2011 20:33
Show Gist options
  • Save pazdera/1121152 to your computer and use it in GitHub Desktop.
Save pazdera/1121152 to your computer and use it in GitHub Desktop.
Example of `builder' design pattern in C++
/*
* Example of `builder' design pattern.
* Copyright (C) 2011 Radek Pazdera
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <iostream>
#include <string>
/* Car parts */
class Wheel
{
public:
int size;
};
class Engine
{
public:
int horsepower;
};
class Body
{
public:
std::string shape;
};
/* Final product -- a car */
class Car
{
public:
Wheel* wheels[4];
Engine* engine;
Body* body;
void specifications()
{
std::cout << "body:" << body->shape << std::endl;
std::cout << "engine horsepower:" << engine->horsepower << std::endl;
std::cout << "tire size:" << wheels[0]->size << "'" << std::endl;
}
};
/* Builder is responsible for constructing the smaller parts */
class Builder
{
public:
virtual Wheel* getWheel() = 0;
virtual Engine* getEngine() = 0;
virtual Body* getBody() = 0;
};
/* Director is responsible for the whole process */
class Director
{
Builder* builder;
public:
void setBuilder(Builder* newBuilder)
{
builder = newBuilder;
}
Car* getCar()
{
Car* car = new Car();
car->body = builder->getBody();
car->engine = builder->getEngine();
car->wheels[0] = builder->getWheel();
car->wheels[1] = builder->getWheel();
car->wheels[2] = builder->getWheel();
car->wheels[3] = builder->getWheel();
return car;
}
};
/* Concrete Builder for Jeep SUV cars */
class JeepBuilder : public Builder
{
public:
Wheel* getWheel()
{
Wheel* wheel = new Wheel();
wheel->size = 22;
return wheel;
}
Engine* getEngine()
{
Engine* engine = new Engine();
engine->horsepower = 400;
return engine;
}
Body* getBody()
{
Body* body = new Body();
body->shape = "SUV";
}
};
/* Concrete builder for Nissan family cars */
class NissanBuilder : public Builder
{
public:
Wheel* getWheel()
{
Wheel* wheel = new Wheel();
wheel->size = 16;
return wheel;
}
Engine* getEngine()
{
Engine* engine = new Engine();
engine->horsepower = 85;
return engine;
}
Body* getBody()
{
Body* body = new Body();
body->shape = "hatchback";
}
};
int main()
{
Car* car; // Final product
/* A director who controls the process */
Director director;
/* Concrete builders */
JeepBuilder jeepBuilder;
NissanBuilder nissanBuilder;
/* Build a Jeep */
std::cout << "Jeep" << std::endl;
director.setBuilder(&jeepBuilder); // using JeepBuilder instance
car = director.getCar();
car->specifications();
std::cout << std::endl;
/* Build a Nissan */
std::cout << "Nissan" << std::endl;
director.setBuilder(&nissanBuilder); // using NissanBuilder instance
car = director.getCar();
car->specifications();
return 0;
}
@ariefroim
Copy link

hi i know you are still working on this example, but there is a small typo in getBody() function: it should return body.
Body* getBody()
{
Body* body = new Body();
body->shape = "hatchback";
return body; // <---- missing
}

The same "typo" exists in the JeepBuilder - getBody method. Enjoy!

@fjrg76-com
Copy link

  1. Don't use the Director object, let your code itself (the client) to call the parts your car needs.
  2. Let the classes Wheel, Engine and Body to return a reference so you can chain the calls so you gain (in the client's side) control of what you're creting.

(Your question has been addressed in the book "Design Patterns in Modern C++20: Reusable Approaches for Object-Oriented Software Design" by Dmitri Nesteruk. Ed. Apress.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment