I have seen chaining of setters (in the context of builder pattern implementations) quite a few times in Java code recently, so I thought I jot down a quick C++ version for future reference (tried to get everything in one class for brevity purposes). No rocket science to be seen here, folks, but still a nice technique for creating objects (*):
class Pizza {
private:
class PizzaProperties {
private:
PizzaProperties() : fSize(0),
fWithCheese(false),
fWithPepperoni(false),
fWithBacon(false) {
}
int fSize;
bool fWithCheese;
bool fWithPepperoni;
bool fWithBacon;
friend class Pizza;
friend class PizzaBuilder;
};
public:
class PizzaBuilder {
public:
PizzaBuilder(int size) {
fProperties.fSize = size;
}
PizzaBuilder& WithCheese() {
fProperties.fWithCheese = true;
return *this;
}
PizzaBuilder& WithPepperoni() {
fProperties.fWithPepperoni = true;
return *this;
}
PizzaBuilder& WithBacon() {
fProperties.fWithBacon = true;
return *this;
}
Pizza Build() {
return Pizza(fProperties);
}
private:
PizzaProperties fProperties;
};
private:
Pizza(const PizzaProperties& properties) : fProperties(properties) {
}
PizzaProperties fProperties;
};
So it’s quite convenient to build up different Pizza objects just by chaining the different “setters” – no need for default parameters, dealing with constructor bloat (# of parameters and # of constructors) etc. Plus, it’s quite efficient because the “setters” return a reference to a Pizza only, no memory allocation needed.
Pizza largeMargheritaPizza =
Pizza::PizzaBuilder(30).WithCheese().Build();
Pizza smallHotPizza =
Pizza::PizzaBuilder(20).WithCheese().WithPepperoni().Build();
(*) The code focusses on the chaining aspect of a builder pattern implementation – not the use of different builder objects for creation.