Join us

Builder Design Pattern in Go

Implementing Builder pattern is to build complex objects piece-by-piece providing more flexibility and readability to the code. In this article, we would learn when and how to implement Builder Pattern to build complex objects.

Builder Design Pattern in Go

Builder Design Pattern in Go

Constructor is also one of the way to create an object and it does have some cons to which Builder pattern covers up very well to create an object piece-by-piece and provides us with more flexibility creating an objects.

Generic approach is implemented in the process of constructing an object so that it can be used to create different representation of same object.

The builder pattern is a design pattern designed to provide a flexible solution to various object creation problems in object-oriented programming.

When to use?

This pattern is to be implemented when:

  1. There is a need to use constructor with long parameter list or multiple constructor with different parameters.
  2. There is a need to build multiple representation of same object, i.e. objects of same class with different characteristics.


Let’s understand the pattern diving into a scenario where you went to create a profile on an E-commerce website.

Creating you profile for the first time will make you enter some of your details:

                constructor: User(firstname, lastname, age, phone, address)

Now let’s say only firstname and lastname is mandatory.

                constructor: User(firstname, lastname)

Based on different combinations of entries made by user multiple constructor needs to be implemented to instantiate an object, making the code complex and multiple entries of constructor added into a class.

How to implement?

Considering the user creating his profile, that code that will be written using builder pattern would be:

                type User struct {
    Firstname, Lastname, Address, Phone string
type UserBuilder struct{
    User *User
func NewUserBuilder(firstname, lastname string) *UserBuilder {
    return &UserBuilder{
            Firstname: firstname,
            Lastname:  lastname,
func (ub *UserBuilder) StaysAt(address string) *UserBuilder {
    ub.User.Address = address
    return ub
func (ub *UserBuilder) ConnectOn(phone string) *UserBuilder {
    ub.User.Phone = phone
    return ub
func (ub *UserBuilder) Build() *User {
    return ub.User
func main() {
    ub := NewUserBuilder("Foo", "Bar")
    user := ub.Build()
    fmt.Println("User: ", *user)        // Output 1
    user = ub.
            StaysAt("ABC City").
    fmt.Println("User: ", *user)        // Output 2

Providing us with output

                Output 1:- User:  {Foo Bar}
Output 2:- User:  {Foo Bar ABC City 0090090090}

In Output 1 returns object with mandatory fields firstname and lastname while on the other hand with Output 2 we were able to add few more details to the same object, providing us with flexibility while creating an instance.

It provides with different set APIs to set properties of an object, in our case it’s StaysAt() and ConnectOn() which are not mandatory but can be used to set properties.

As the above created User object does not have setter methods so the object cannot be updated, providing it an immutability.


  1. Constructor’s parameters decreases and provides highly readable method calls.
  2. No need to pass null to optional parameters of constructor while creating an instance.
  3. Objects is always instantiated in a complete state.
  4. Immutable objects are created without complex logic.


  1. Number of lines of code increases.
  2. Separate builder needs to be created for each different Product.

Happy Coding…!!!

More Readings:

Scheduling Jobs in Golang

Only registered users can post comments. Please, login or signup.

Start blogging about your favorite technologies, reach more readers and earn rewards!

Join other developers and claim your FAUN account now!


Pravand katyare

Senior Software Engineer, Siemens

User Popularity



Total Hits