Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Singleton in go

How does one implement the Singleton design pattern in the go programming language?

like image 437
Ben Noland Avatar asked Dec 01 '09 00:12

Ben Noland


People also ask

When to use singleton in Golang?

Introduction: Singleton Design Pattern is a creational design pattern and also one of the most commonly used design pattern. This pattern is used when only a single instance of the struct should exist.

Why singleton is not good?

By using singletons in your project, you start to create technical debt. Singletons tend to spread like a virus because it's so easy to access them. It's difficult to keep track of where they're used and getting rid of a singleton can be a refactoring nightmare in large or complex projects.

Why singleton?

A singleton should be used when managing access to a resource which is shared by the entire application, and it would be destructive to potentially have multiple instances of the same class. Making sure that access to shared resources thread safe is one very good example of where this kind of pattern can be vital.


1 Answers

Setting aside the argument of whether or not implementing the singleton pattern is a good idea, here's a possible implementation:

package singleton  type single struct {         O interface{}; }  var instantiated *single = nil  func New() *single {         if instantiated == nil {                 instantiated = new(single);         }         return instantiated; } 

single and instantiated are private, but New() is public. Thus, you can't directly instantiate single without going through New(), and it tracks the number of instantiations with the private boolean instantiated. Adjust the definition of single to taste.

However, as several others have noted, this is not thread-safe, unless you're only initializing your singleton in init(). A better approach would be to leverage sync.Once to do the hard work for you:

package singleton  import "sync"  type single struct {         O interface{}; }  var instantiated *single var once sync.Once  func New() *single {         once.Do(func() {                 instantiated = &single{}         })         return instantiated } 

See also, hasan j's suggestion of just thinking of a package as a singleton. And finally, do consider what others are suggesting: that singletons are often an indicator of a problematic implementation.

like image 116
esm Avatar answered Sep 24 '22 23:09

esm