Bridge Design Pattern in Go
Tags: go, design, productivity, programming
Published: 2020-11-25 14:07:42

Hey there!

Another week, another design pattern. This week I'm bringing you the Bridge Desing Pattern.

Let's assume you are working with shapes. Thus far you've implemented a Square and a Circle with a getArea() and a getPerimeter() functions.

```golang
type Shape interface {
	getArea() float32
	getPerimeter() float32
}
```

```golang
type Square struct {
	side   float32
}

func (s *Square) getArea() float32 {
	return s.side * s.side
}

func (s *Square) getPerimeter() float32 {
	return s.side * 4
}

func NewSquare(side float32) *Square {
	s := &Square{side: side}
	return s
}
```

```golang
type Circle struct {
	radius float32
}

func (c *Circle) getArea() float32 {
	return math.Pi * c.radius * c.radius
}

func (c *Circle) getPerimeter() float32 {
	return 2 * math.Pi * c.radius
}

func NewCircle(radius float32) *Circle {
	c := &Circle{radius: radius}
	return c
}
```

However, you want to add Colour to your shapes and you want to print the colour for each shape. You would find yourself with a complicated and exponentially growing tree of coloured shapes like this: 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/i7zi9unw2a476kasqfbn.png)

If you keep adding shapes and colours, you'd get a lot of different objects which would actually behave similarly and would be tedious, awful and inefficient to escalate.

So we are going to use the bridge pattern for this issue.

Let's define a new Colour interface which will enforce a printColour() method on the implementing structs:

```golang
type Colour interface {
	printColour()
}
```

Then we can create new colour structures which will implement the printColour() method on their own way:

```golang
type RedColour struct{}

func (r *RedColour) printColour() {
	fmt.Println("I'm Red!")
}
```

```golang
type BlueColour struct {
}

func (b *BlueColour) printColour() {
	fmt.Println("I'm Blue!")
}
```

So now we can actually add the colour attribute to our shapes and add the colour methods that we want to impose on our shape interface:

```golang
type Shape interface {
	getArea() float32
	getPerimeter() float32
	getColour()
	setColour(colour Colour)
}
```

Again, let's go back to our shapes structs and implement the methods:

```golang
func (s *Square) setColour(colour Colour) {
	s.colour = colour
}

func (s *Square) getColour() {
	fmt.Print("Square says: ")
	s.colour.printColour()
}
```

```golang
func (c *Circle) setColour(colour Colour) {
	c.colour = colour
}

func (c *Circle) getColour() {
	fmt.Print("Circle says: ")
	c.colour.printColour()
}
```

Right now, our program will look something like this:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/aahvqut245zzjl74afeb.png)

Since everything was set up, let's test it on our main method:

```golang
func main() {
	r := &RedColour{}
	b := &BlueColour{}

	s := NewSquare(4.2, r)
	c := NewCircle(6.9, b)

	fmt.Println("Square's area is:", s.getArea())
	fmt.Println("Square's perimeter is:", s.getPerimeter())
	s.getColour()

	s.setColour(b)
	s.getColour()

	fmt.Println()

	fmt.Println("Circle's area is:", c.getArea())
	fmt.Println("Circle's perimeter is:", c.getPerimeter())
	c.getColour()

	c.setColour(r)
	c.getColour()
}
```

And the result will look like this:

```bash
go run .                                                                                     
Square's area is: 17.639997
Square's perimeter is: 16.8
Square says: I'm Red!
Square says: I'm Blue!

Circle's area is: 149.57124
Circle's perimeter is: 43.35398
Circle says: I'm Blue!
Circle says: I'm Red!
```

And that's it for today! I hope you liked it and it proves useful for your projects.

Happy coding!