Engineering Blog


Interface Pollution in Golang

Interfaces are one of the cornerstones of the Go language when designing and structuring our code. However, like many tools or concepts, abusing them is generally not a good idea. Interface pollution is about overwhelming our code with unnecessary abstractions, making it harder to understand. So, first we understand the concept of interface and then about interface pollution.

Concept of interface

In Go, an interface is a set of method signatures. When a type provides definition for all the methods in the interface, it is said to implement the interface. It is much similar to the OOP world. Interface specifies what methods a type should have and the type decides how to implement these methods. An interface provides a way to specify the behavior of an object. We use interfaces to create common abstractions that multiple objects can implement. You can create an interface in golang using following syntax:-

type interface_name interface{
 //methods signature
 fun1() int
 fun2() string

When to use interfaces

When should we create interfaces in Go? There are three concrete use cases where interfaces are usually considered to bring value.

  • Common behaviour
  • Decoupling
  • Restricting behavior

Common behaviour

We can use interfaces when multiple methods implement a common behavior. In such cases, we can factor out behavior inside an interface. This type of interface also has a strong potential for reusability.


Another important use case is about decoupling our code from an implementation. If we rely on an abstraction instead of a concrete implementation, the implementation itself can be replaced with another without even having to change our code. One benefit of decoupling can be related to unit testing. For instance for test cases we can:-

  • Use the concrete implementation via integration tests
  • Use a mock (or any kind of test double) via unit tests
  • Or both

Restricting Behavior

The last use case we will discuss can be pretty counter intuitive at first sight. It’s about restricting a type to a specific behavior like when we want to only change a certain field or behaviour of our implementation but other field should be read-only. we can use interfaces to restrict a type to a specific behavior for various reasons, such as semantics enforcement.

In this section, we saw three potential use cases where interfaces are generally considered as bringing value: factoring out a common behavior, creating some decoupling, and restricting a type to a certain behavior. Again, this list isn’t exhaustive, but it should give us a general understanding of when interfaces are helpful in Go.

Interface pollution

It’s fairly common to see interfaces being overused in Go projects. Interfaces are made to create abstractions and we should remember that abstractions should be discovered, not created. It means we shouldn’t start creating abstractions in our code if there is no immediate reason to do so. So, we should create an interface when we need it, not when we foresee that we could need it.

The main problem if we overuse interfaces are:-

  • They make code flow more complex
  • Adding a useless level of indirection doesn’t bring any value; it creates a worthless abstraction making the code more difficult to read, understand, and reason about

In summary, we should be cautious when creating abstractions in our code abstractions should be discovered, not created. It’s common for us, software developers, to overengineer our code by trying to guess what the perfect level of abstraction is, based on what we think we might need later. This process should be avoided because, in most cases, it pollutes our code with unnecessary abstractions, making it more complex to read.

Let’s not try to solve a problem abstractly but solve what has to be solved now. Last, but not least, if it’s unclear how an interface makes the code better, we should probably consider removing it to make our code simpler.


  • 100 Go Mistakes and how to avoid them, Teiva Harsanyi, Manning Publications Co
Previous Post
Next Post