# Notes: Go Design Patterns - Adapter Pattern

Adapter design pattern as the name suggests lets an interface adapt to another similar interface. This is a structural pattern. Let's dive directly into the example.

Let's assume that we have a `DataParser` interface that contains methods around *JSON* formatted data. I'm adding a very simple interface where we have one method which just parses *JSON* data:
```
type DataParser interface {
	parseJSON(string) *User
}
```

Now let's say later on we want to add *XML* parser as well. Now that our code has implementations of `DataParser` everywhere, it'd be really difficult to change everything again to include XML parser.

So, to avoid this situation what we can do is we can create an adapter that encapsulates XML parser but implements all the `DataParser`methods. So, whenever we have to use XML parser, we can use the adapter instead.

Adapter could look like this:
```
type XMLToJSONAdapter struct {
	XMLParser *XMLParser
}
```

and its `DataParser` method implementation could be as simple as this:
```
func (a *XMLToJSONAdapter) parseJSON(userSerialized string) *User {
	return a.XMLParser.parseXML(userSerialized)
}
```

As you can see, internally `parseJSON` is calling XML Parser only. This way everything works without making a lot of changes.

Complete working code:
```
package main

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

type User struct {
	Name     string   `json:"name" xml:"name"`
	Age      int      `json:"age" xml:"age"`
	Skills   []string `json:"skills" xml:"skills"`
	IsActive bool     `json:"isActive" xml:"isActive"`
}

type DataParser interface {
	parseJSON(string) *User
}

type JSONParser struct{}

func (p *JSONParser) parseJSON(userSerialized string) *User {
	var user User

	err := json.Unmarshal([]byte(userSerialized), &user)

	if err != nil {
		fmt.Println(err.Error())
	}

	return &user
}

// now we want to add a new XML parser
// implementing legacy DataParser interface
type XMLParser struct{}

func (p *XMLParser) parseXML(userSerialized string) *User {
	var user User

	err := xml.Unmarshal([]byte(userSerialized), &user)

	if err != nil {
		fmt.Println(err.Error())
	}

	return &user
}

// adapter to convert XML parser
// to JSON parser i.e. to implement
// DataParser interface
type XMLToJSONAdapter struct {
	XMLParser *XMLParser
}

func (a *XMLToJSONAdapter) parseJSON(userSerialized string) *User {
	return a.XMLParser.parseXML(userSerialized)
}

func main() {
	jsonData := `{
		"name": "nidhi pandey",
		"age": 30,
		"skills": ["qa", "testing", "coding"],
		"isActive": false
	}`

	xmlData := `<?xml version="1.0" encoding="UTF-8" ?>
	<root>
		<name>kshitij kumar</name>
		<age>21</age>
		<skills>backend</skills>
		<skills>frontend</skills>
		<isActive>true</isActive>
	</root>`

	jsonParser := JSONParser{}
	fmt.Printf("Parsed JSON: %#v\n\n", jsonParser.parseJSON(jsonData))

	xmlParserAdapter := XMLToJSONAdapter{}
	fmt.Printf("Parsed XML: %#v\n\n", xmlParserAdapter.parseJSON(xmlData))
}

```
