Go

Go

Made by DeepSource

Use consistent method receiver names SCC-ST1016

Style
Minor

As our codebase grows, eventually we'll need to refactor some of it.

For example, consider moving pieces of code between levels abstractions or from higher levels of abstraction into a lower level.

Imagine taking this snippet from a higher-level container like Room which holds groups of users in a server, and moving it up or down one level:

func (this *Room) Announce() {
    srv := this.Server()
    for _, c := range srv.Clients() {
        // Send announcement to all clients about a new room
        c.Send(srv.RenderAnnouncement(this))
    }
}

// Moved between...

func (this *Server) AddRoom(room *Room) {
    for _, c := rnge this.Clients() {
        // Send announcement to all clients about a new room
        c.Send(this.RenderAnnouncement(room))
    }
}

When using this, there is confusion about whether we're referring to the server or the room as we're moving the code between.

-       c.Send(this.RenderAnnouncement(room))
+       c.Send(srv.RenderAnnouncement(this))

Refactoring this kind of code produce some bugs and having to edit all the little innards does make moving code around more tedious.

Moving across levels of abstraction is a great example of when consistently well-named receivers make a huge difference:

func (room *Room) Announce() {
    srv := room.Server()
    for _, c := range srv.Clients() {
        // Send announcement to all clients about a new room
        c.Send(srv.RenderAnnouncement(room))
    }
}

// Moved between...

func (srv *Server) AddRoom(room *Room) {
    for _, c := range srv.Clients() {
        // Send announcement to all clients about a new room
        c.Send(srv.RenderAnnouncement(room))
    }
}

This is a great little pattern to keep everything working despite moving between layers of abstraction. Note how the inner code stays identical and all we're doing is sometimes adding a little extra context outside of it.

As projects mature, this kind of refactoring happens surprisingly often. We're talking about just one line in this example, but the same applies for larger chunks too. If the receivers are named similarly, then these code blocks can be moved wholesale between layers of abstraction with minimal hassle and helps us avoid careless bugs.