Engineering Blog

                            

Interface on producer side

Interfaces are used to create common abstractions that multiple objects can implement. Before delving into this topic, let’s make sure the terms we use throughout this section are clear:

  • Producer side – An interface defined in the same package as the concrete implementation
  • Consumer side – An interface define in an external package where it is used

It’s common to see developers creating interfaces on the producer side, alongside the concrete implementation. But in Go, in most cases, this is not what we should do. Here, we create a specific package to store and retrieve customer data. Meanwhile, still in the same package, we decide that all the calls have to go through the following interface:


package store

type CustomerStorage interface {
StoreCustomer(customer Customer) error
GetCustomer(id string) (Customer, error)
UpdateCustomer(customer Customer) error
GetAllCustomers() ([]Customer, error)
GetCustomersWithoutContract() ([]Customer, error)
GetCustomersWithNegativeBalance() ([]Customer, error)
}

In the above example interface is exposed on the producer side. This isn’t the best practice in GO. As mentioned, interfaces are satisfied implicitly in Go, which tends to be a game-changer compared to languages with an explicit implementation. This means that it’s not up to the producer to force a
given abstraction for all the clients. Instead, it’s up to the client to decide whether it needs some form of abstraction and then determine the best abstraction level for its
needs.

One client won’t be interested in decoupling its code. Maybe another client wants to decouple its code but is only interested in the GetAllCustomers method. In this case, this client can create an interface with a single method, referencing the Customer struct from the external package:

package client
type customersGetter interface {
GetAllCustomers() ([]store.Customer, error)
}

Here, the best approach is to expose the concrete implementation on the producer side and let the client decide how to use it and whether an abstraction is needed.

Previous Post
Next Post