Golang Tips & Tricks #2 - interfaces

When it comes to interfaces, a good practice is to create an interface where you’ll use it. Creating interfaces in advanced is not recommended in Go. There are two exceptions:

  • you’re creating a library which will be used in different projects
  • you’ll have more than 1 implementation

In the example below, we have a storage implementation.

type inMemoryStorage struct {
   mutex *sync.Mutex
   storage map[string]*Value
}

func NewStorage() *inMemoryStorage {
   return &inMemoryStorage{
      storage: map[string]*Value{},
      mutex: &sync.Mutex{},
   }
}

func (s inMemoryStorage) Set(ctx context.Context, value *Value) error  {
   s.mutex.Lock()
   s.storage[value.key] = value
   s.mutex.Unlock()
   return nil
}

func (s inMemoryStorage) Get(ctx context.Context, key string)  (*Value, error)  {
   if val, ok := s.storage[key]; ok {
      return val, nil
   }

   return nil, nil
}

func (s inMemoryStorage) GetAll(ctx context.Context)  map[string]*Value  {
   return s.storage
}

func (s inMemoryStorage) Remove(ctx context.Context, key string) error  {
   s.mutex.Lock()
   delete(s.storage, key)
   s.mutex.Unlock()
   return nil
}

As you can see, we skipped the interface(s) because they are not needed here.

Why do we have this rule? Imagine the situation when you add the interface next to the implementation. The interface is used for abstracting (dependency injection). The interface can look like the below.

type Storager interface {
   Set(ctx context.Context, value *Value) error
   Get(ctx context.Context, key string) (*Value, error)
   GetAll(ctx context.Context) map[string]*Value
   Remove(ctx context.Context, key string) error
}

The problem with the approach comes, for example, in testing. In our production code, you may use only Set method, but you have to mock all of them. It’s better to split the interface to smaller parts and define only those methods which are really needed.

type Remover interface {
   Remove(ctx context.Context, key string) error
}
golang   tipstricks
Published in: Golang
Did you like the post?
or

About the author

Hi! My name is Bartek. I'm a developer since 2011. I love to learn by sharing the knowledge. You can find me on Twitter or Linkedin. I'm a backend engineer at Brainly.

Recent posts

I want to help you become a developer

That's why I can let you know about new blogposts on your email

You can find me

You May Also Enjoy

Golang Tips & Tricks #4 - internal folders 25 Mar 2019

While developing a library, we create a directory structure to keep the code organized. However, some exported functions or struct should not be used by users of the library. The achieve that, call...
golang   tipstricks
read more...

Golang Tips & Tricks #3 - graceful shutdown 18 Mar 2019

In the microservices' world, one thing what's worth considering is a graceful shutdown. This is important to not lose data while shutting down a container. The container orchestrator like Kubernete...
golang   tipstricks
read more...

Golang Tips & Tricks #1 - errors 04 Mar 2019

You should use the package github.com/pkg/errors instead of errors package for errors in your applications. The default package lacks a few things like: stack trace easy appending message to ...
golang   tipstricks
read more...