DEV Community

Cover image for Bridge Design Pattern in Go
Tomas Sirio
Tomas Sirio

Posted on

Bridge Design Pattern in Go

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.

type Shape interface {
    getArea() float32
    getPerimeter() float32
}
Enter fullscreen mode Exit fullscreen mode
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
}
Enter fullscreen mode Exit fullscreen mode
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
}
Enter fullscreen mode Exit fullscreen mode

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

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:

type Colour interface {
    printColour()
}
Enter fullscreen mode Exit fullscreen mode

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

type RedColour struct{}

func (r *RedColour) printColour() {
    fmt.Println("I'm Red!")
}
Enter fullscreen mode Exit fullscreen mode
type BlueColour struct {
}

func (b *BlueColour) printColour() {
    fmt.Println("I'm Blue!")
}
Enter fullscreen mode Exit fullscreen mode

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:

type Shape interface {
    getArea() float32
    getPerimeter() float32
    getColour()
    setColour(colour Colour)
}
Enter fullscreen mode Exit fullscreen mode

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

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

func (s *Square) getColour() {
    fmt.Print("Square says: ")
    s.colour.printColour()
}
Enter fullscreen mode Exit fullscreen mode
func (c *Circle) setColour(colour Colour) {
    c.colour = colour
}

func (c *Circle) getColour() {
    fmt.Print("Circle says: ")
    c.colour.printColour()
}
Enter fullscreen mode Exit fullscreen mode

Right now, our program will look something like this:

Alt Text

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

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()
}
Enter fullscreen mode Exit fullscreen mode

And the result will look like this:

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!
Enter fullscreen mode Exit fullscreen mode

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

Happy coding!

Top comments (2)

Collapse
 
davidkroell profile image
David Kröll • Edited

Hi, nice to know the name of a very common design pattern which I often use. In case you'd like to get rid of the grid lines from your draw.io drawings (I guessed you used that) you may also export it as image. As I did in my recent post: dev.to/davidkroell/go-concurrency-...

Collapse
 
tomassirio profile image
Tomas Sirio

Thanks! I didn't know how to do it. I'll start exporting the images from now on