---
title: Adapter Pattern
tags: "Design Patterns"
---
## Adapter Pattern
- The Adapter Pattern is a structural design pattern that allows objects with incompatible interfaces to collaborate.
- It acts as a bridge between two incompatible interfaces, making them work together.
### Example
Suppose we have a system with two types of birds: Ducks and Turkeys.
We want to make Ducks and Turkeys compatible with a common interface called "Duck."
### Duck and Turkey Interfaces
We have a Duck interface:
```go
type Duck interface {
Quack()
Fly()
}
```
We have a Turkey interface:
```go
type Turkey interface {
Gobble()
Fly()
}
```
### Duck and Turkey Implementations
We have a MallardDuck:
```go
type MallardDuck struct{}
func (m *MallardDuck) Quack() {
fmt.Println("Quack")
}
func (m *MallardDuck) Fly() {
fmt.Println("I'm flying")
}
```
We have a WildTurkey:
```go
type WildTurkey struct{}
func (w *WildTurkey) Gobble() {
fmt.Println("Gobble gobble")
}
func (w *WildTurkey) Fly() {
fmt.Println("I'm flying a short distance")
}
```
### Adapter
Adapter for Turkey:
```go
type TurkeyAdapter struct {
turkey Turkey
}
func (t *TurkeyAdapter) Quack() {
t.turkey.Gobble()
}
func (t *TurkeyAdapter) Fly() {
for i := 0; i < 5; i++ {
t.turkey.Fly()
}
}
```
### Use the Adapter to make a Turkey compatible with a Duck
```go
func main() {
duck := &MallardDuck{}
turkey := &WildTurkey{}
turkeyAdapter := &TurkeyAdapter{turkey: turkey}
fmt.Println("The Turkey says...")
turkey.Gobble() // Gobble gobble
turkey.Fly() // I'm flying a short distance
fmt.Println("\nThe Duck says...")
testDuck(duck)
// Quack
// I'm flying
fmt.Println("\nThe TurkeyAdapter says...")
testDuck(turkeyAdapter)
// Gobble gobble
// I'm flying a short distance
// I'm flying a short distance
// I'm flying a short distance
// I'm flying a short distance
// I'm flying a short distance
}
func testDuck(duck Duck) {
duck.Quack()
duck.Fly()
}
```
### Drone Example
The interface and implementation for a Drone:
```go
type Drone interface {
Beep()
SpinRotors()
TakeOff()
}
type SuperDrone struct{}
func (s *SuperDrone) Beep() {
fmt.Println("Beep beep beep")
}
func (s *SuperDrone) SpinRotors() {
fmt.Println("Rotors are spinning")
}
func (s *SuperDrone) TakeOff() {
fmt.Println("Taking off")
}
```
The adapter for a Drone:
```go
type DroneAdapter struct {
drone Drone
}
func (d *DroneAdapter) Quack() {
d.drone.Beep()
}
func (d *DroneAdapter) Fly() {
d.drone.SpinRotors()
d.drone.TakeOff()
}
```
Use the adapter to make a Drone compatible with a Duck:
```go
func main() {
drone := &SuperDrone{}
droneAdapter := &DroneAdapter{drone: drone}
fmt.Println("\nThe DroneAdapter says...")
testDuck(droneAdapter)
// Beep beep beep
// Rotors are spinning
// Taking off
}
```
### Summary
- The Adapter Pattern allows us to make incompatible interfaces work together.
- It promotes reusability of existing code.
- It is helpful to integrate legacy or third-party code into our system.