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 #6 - the _test package 14 Aug 2019

Testing is one of the hardest stuff in programming. Today trick will help you organize your tests and the production code. Let's assume you have a package called `orders`. When you want to separat...
golang   tipstricks   tests
read more...

Golang Tips & Tricks #5 - blank identifier in structs 22 Jul 2019

While working with structures, there's a possibility to initialize the structure without providing the keys of fields. ```go type SomeSturct struct { FirstField string SecondField bool } // ....
golang   tipstricks
read more...

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...