In software engineering, Creational Design Patterns deal with object creation mechanisms, trying to create objects in a manner suitable to the situation. The basic or ordinary form of object creation could result in design problems or added complexity to the design. Builder Design Pattern in C++ solves this specific problem by . separating the construction of a complex object from its representation By the way, If you haven’t check out my other articles on Creational Design Patterns, then here is the list: Factory Builder Prototype Singleton The code snippets you see throughout this series of articles are simplified not sophisticated. So you often see me not using keywords like override, final, public(while inheritance) just to make code compact & consumable(most of the time) in single standard screen size. I also prefer struct instead of class just to save line by not writing “public:” sometimes and also miss , constructor, , prefix std::, deleting dynamic memory, intentionally. virtual destructor copy constructor I also consider myself a pragmatic person who wants to convey an idea in the simplest way possible rather than the standard way or using Jargons. Note: If you stumbled here directly, then I would suggest you go through first, even if it is trivial. I believe it will encourage you to explore more on this topic. What is design pattern? All of this code you encounter in this series of articles are compiled using C++20(though I have used features up to C++17 in most cases). So if you don’t have access to the latest compiler you can use which has preinstalled boost library as well. Modern C++ https://wandbox.org/ Intent To create/instantiate complex & complicated object piecewise & succinctly by providing an API in a separate entity. Builder Design Pattern is used when we want to construct a complex object. However, we do not want to have a complex constructor member or one that would need many arguments. The Builder Design Pattern constructs a complex object step by step & the final step will return the object. The process of constructing an object should be generic so that it can be used to create different representations of the same object with the help of a variety of methods. Life Without Builders Suppose you have to create the HTML generator using C++ then very naïve way to do it is : text = ; output; output += ; output += text; output += ; ( , text); words[] = { , }; oss; oss << ; ( w : words) oss << << w << ; oss << ; (oss.str().c_str()); // <p>hello</p> auto "hello" string "<p>" "</p>" printf "<p>%s</p>" // <ul><li>hello</li><li>world</li></ul> string "hello" "world" ostringstream "<ul>" for auto " <li>" "</li>" "</ul>" printf A sophisticated dev will create a class with a bunch of constructor argument & method to add a child node. This is a good approach though but it may complicate the object representation. In general, some objects are simple & can be created in a single constructor call while other objects require a lot of ceremonies to create. Having an object with 10 constructor arguments is not productive. Instead, we should opt for piecewise construction. Builder provides an API for constructing an object step-by-step without revealing actual object representation. Builder Design Pattern Example in Modern C++ m_name; m_text; <HtmlElement> m_childs; m_indent_size = ; HtmlElement() = ; HtmlElement( &name, &text) : m_name(name), m_text(text) {} : { oss; oss << (m_indent_size * indent, ) << << m_name << << ; (m_text.size()) oss << (m_indent_size * (indent + ), ) << m_text << ; ( &element : m_childs) oss << element.str(indent + ); oss << (m_indent_size * indent, ) << << m_name << << ; oss.str(); } <HtmlBuilder> build( root_name) { make_unique<HtmlBuilder>(root_name); } }; HtmlElement m_root; : HtmlBuilder( root_name) { m_root.m_name = root_name; } { m_root.m_childs.emplace_back(HtmlElement{child_name, child_text}); ; } { m_root.str(); } { m_root; } }; { builder = HtmlElement::build( ); builder->add_child( , )->add_child( , ); << builder->str() << ; EXIT_SUCCESS; } ; class HtmlBuilder { class HtmlElement string string vector constexpr static size_t 4 default const string const string friend ; class HtmlBuilder public string str ( indent = ) int32_t 0 ostringstream string ' ' "<" ">" endl if string 1 ' ' endl for auto 1 string ' ' "</" ">" endl return static unique_ptr string return { class HtmlBuilder public string HtmlBuilder * add_child ( child_name, child_text) string string return this string str () return operator HtmlElement () return int main () auto "ul" "li" "hello" "li" "world" cout endl return /* <ul> <li> hello </li> <li> world </li> </ul> */ We are forcing users here to use builder by making data members of HtmlElements private. As you can see, we have declared the HtmlBuilder & HtmlElement in the same file & to do so, we need forward declaration i.e. class HtmlBuilder; as it is an . And we can not create the object of incomplete type before compiler parses its actual declaration. The reason is simple, the compiler needs the size of an object to allocate memory for it. Hence pointer is only way around so we have taken <HtmlBuilder>. incomplete type unique_ptr Sophisticated & Fluent Builder Design Pattern Example Following is the more sophisticated example of the Builder Design Pattern in C++ organized in four different files (i.e. Person.h, Person.cpp, PersonBuilder.h PersonBuilder.cpp). Person.h ; :: m_name, m_street_address, m_post_code, m_city; :: m_company_name, m_position, m_annual_income; Person( :: name) : m_name(name) {} : ostream& <<(ostream& os, Person& obj); ; }; # once pragma # include <iostream> using namespace std ; class PersonBuilder { class Person std string // Personal Detail std string // Employment Detail std string public friend ; class PersonBuilder friend operator const PersonBuilder static create ( :: name) std string Person.cpp PersonBuilder Person::create( name) { PersonBuilder{name}; } ostream& <<(ostream& os, Person& obj) { os << obj.m_name << :: << << :: << << obj.m_street_address << << obj.m_post_code << << obj.m_city << :: << << :: << << obj.m_company_name << << obj.m_position << << obj.m_annual_income; } # include <iostream> # include "Person.h" # include "PersonBuilder.h" string return operator const return std endl "lives : " std endl "at " " with postcode " " in " std endl "works : " std endl "with " " as a " " earning " As you can see from the above example Person may have many details like Personal & Professional. And so does the count of data members. In our case, there are 7 data members. Having a single class for all the actions needed to create a Person through constructor might make our class bloated & lose its original purpose. Moreover, the library user needs to take care of all those constructor parameters sequence. PersonBuilder.h Person person; : PersonBuilder( name) : person(name) {} { move(person); } ; ; ; ; ; ; ; ; }; # once pragma # include "Person.h" { class PersonBuilder public string operator Person () const return PersonBuilder& lives () PersonBuilder& at ( :: street_address) std string PersonBuilder& with_postcode ( :: post_code) std string PersonBuilder& in ( :: city) std string PersonBuilder& works () PersonBuilder& with ( company_name) string PersonBuilder& as_a ( position) string PersonBuilder& earning ( annual_income) string PersonBuilder.cpp PersonBuilder& PersonBuilder::lives() { * ; } PersonBuilder& PersonBuilder::works() { * ; } PersonBuilder& PersonBuilder::with( company_name) { person.m_company_name = company_name; * ; } PersonBuilder& PersonBuilder::as_a( position) { person.m_position = position; * ; } PersonBuilder& PersonBuilder::earning( annual_income) { person.m_annual_income = annual_income; * ; } PersonBuilder& PersonBuilder::at( :: street_address) { person.m_street_address = street_address; * ; } PersonBuilder& PersonBuilder::with_postcode( :: post_code) { person.m_post_code = post_code; * ; } PersonBuilder& PersonBuilder::in( :: city) { person.m_city = city; * ; } # include "PersonBuilder.h" return this return this string return this string return this string return this std string return this std string return this std string return this Rather stuffing all those construction related APIs into Person, we can delegate that task to separate entity i.e. PersonBuilder. Main.cpp ; { Person p = Person::create( ) .lives() .at( ) .with_postcode( ) .in( ) .works() .with( ) .as_a( ) .earning( ); << p << ; EXIT_SUCCESS; } # include <iostream> # include "Person.h" # include "PersonBuilder.h" using namespace std int main () "John" "123 London Road" "SW1 1GB" "London" "PragmaSoft" "Consultant" "10e6" cout endl return Isn’t the above construction looks more intuitive, natural & plain English? If you are concerned about blank methods like lives() & works(), then do not worry, it will be eliminated in optimization. You can also observe that we are forcing user’s to use builder rather than constructor by making the constructor private & exposing only create std::string name API. ( ) Do not over complicate things by designing an interface or abstract classes unless you need it. I have seen this in many Builder Design Pattern Examples on Web. Benefits of Builder Design Pattern The number of lines of code increases at least to double in builder pattern. But the effort pays off in terms of design flexibility, fewer or no parameters to the constructor and much more readable code. Builder Design Pattern also helps in minimizing the number of parameters in constructor & thus there is no need to pass in for optional parameters to the constructor. null Immutable objects can be built without much complex logic in the object building process. Segregating construction from makes the object representation slice & precise. Having a builder entity separate provides the flexibility of creating & instantiating different objects representations. object representation Summary by FAQs When should the Builder Design Pattern be used? Whenever creation of new object requires setting many parameters and some of them (or all of them) are optional. Why do we need a Builder class when implementing a Builder Design Pattern? It isn’t necessary but there are some benefits in doing so: The concern of building object should be in the separate entity as per . SRP The original object would not be bloated. Easy & maintainable code. Testing & understanding a constructor with many input arguments gets exponentially more complicated. Greatest Advantage of Builder Design Pattern! More expressive code. MyClass o = new MyClass(5, 5.5, 'A', var, 1000, obj9, "hello"); Instead MyClass o = MyClass.builder().a(5).b(5.5).c('A').d(var).e(1000).f(obj9).g("hello"); You can see which data member is being assigned by what & even change the order of assignment. What’s the difference between Abstract Factory and Builder Design Pattern? Factory produces the objects in wholesale that could be any object from inheritance hierarchy(like Point, Point2D, Point3D). While Builder deals with instantiation of an object that is limited to a single object(Although this statement is still debatable). You see Factory is all about wholesale object creation while the builder is piecewise object creation. In both the patterns, you can separate out the mechanism related to object creation in other classes. Previously published at http://www.vishalchovatiya.com/builder-design-pattern-in-modern-cpp/