# Notes: Go Design Patterns - Builder Pattern

Builder pattern builds complex objects using simple objects and using a step-by-step approach. This type of design pattern comes under creational pattern.

In our example, we are building `Message`.
```
type Message struct {
	Data   string
	Format string
}
```
To build message we require some fields like recipient, sender, and content. So, builders should follow `MessageBuilder` interface.
```
type MessageBuilder interface {
	SetRecipient(recipient string)
	SetSender(sender string)
	SetContent(content string)
	BuildMessage() (*Message, error) // returns the built message
}
```

Now, we have used two different kinds of builders `JSONMessageBuilder` and `XMLMessageBuilder` to build messages in *JSON* and *XML* formats respectively.

Now, to build message without knowing about the concrete type, we have a director which takes `MessageBuilder` interface objects as input and gives a concrete-built `Message`. We call our director `Sender` and here is what it looks like:
```
type Sender struct{}

func (s *Sender) BuildMessage(builder MessageBuilder) (*Message, error) {
	builder.SetRecipient("Kshitij Kumar")
	builder.SetSender("Nidhi Pandey")
	builder.SetContent("Where is my birthday gift?")
	return builder.BuildMessage()
}
```
Complete working code where you can see the complete result:

```
package main

import (
	"encoding/json"
	"encoding/xml"
	"fmt"
)

// we'll be building "Message"
type Message struct {
	Data   string
	Format string
}

// builder interface to build Message
type MessageBuilder interface {
	SetRecipient(recipient string)
	SetSender(sender string)
	SetContent(content string)
	BuildMessage() (*Message, error) // returns the built message
}

type CommonMessageBuilderFields struct {
	MessageRecipient string `json:"recipient" xml:"recipient"`
	MessageSender    string `json:"sender" xml:"sender"`
	MessageContent   string `json:"content" xml:"content"`
}

// JSON message builder
type JSONMessageBuilder struct {
	CommonMessageBuilderFields
}

func (b *JSONMessageBuilder) SetRecipient(recipient string) {
	b.MessageRecipient = recipient
}

func (b *JSONMessageBuilder) SetSender(sender string) {
	b.MessageSender = sender
}

func (b *JSONMessageBuilder) SetContent(content string) {
	b.MessageContent = content
}

func (b *JSONMessageBuilder) BuildMessage() (*Message, error) {
	data, err := json.Marshal(b)
	if err != nil {
		return nil, err
	}

	return &Message{Data: string(data), Format: "JSON"}, nil
}

// XML message builder
type XMLMessageBuilder struct {
	CommonMessageBuilderFields
}

func (b *XMLMessageBuilder) SetRecipient(recipient string) {
	b.MessageRecipient = recipient
}

func (b *XMLMessageBuilder) SetSender(sender string) {
	b.MessageSender = sender
}

func (b *XMLMessageBuilder) SetContent(content string) {
	b.MessageContent = content
}

func (b *XMLMessageBuilder) BuildMessage() (*Message, error) {
	data, err := xml.Marshal(b)
	if err != nil {
		return nil, err
	}

	return &Message{Data: string(data), Format: "XML"}, nil
}

// director of the message builder
type Sender struct{}

// this builds concrete message
func (s *Sender) BuildMessage(builder MessageBuilder) (*Message, error) {
	builder.SetRecipient("Kshitij Kumar")
	builder.SetSender("Nidhi Pandey")
	builder.SetContent("Where is my birthday gift?")
	return builder.BuildMessage()
}

func main() {
	sender := &Sender{}

	jsonMsg, err := sender.BuildMessage(&JSONMessageBuilder{})
	if err != nil {
		panic(err)
	}

	fmt.Printf("%#v\n\n", jsonMsg)

	xmlMsg, err := sender.BuildMessage(&XMLMessageBuilder{})
	if err != nil {
		panic(err)
	}

	fmt.Printf("%#v\n", xmlMsg)
}

```
