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.