DEV Community

Kittipat.po
Kittipat.po

Posted on • Updated on

Understanding the Singleton Pattern in Go

Singleton Pattern

The Singleton Pattern is a creational design pattern that ensures a class has only one instance and provides a global point of access to that instance. This pattern is particularly useful when there's a need to coordinate actions that can't be shared among multiple instances.

Implementing the Singleton Pattern in Go

Let's dive into a practical example of implementing the Singleton Pattern in Go. We'll create a DriverPg type that represents a PostgreSQL database driver connection. The Connect function initializes and returns the singleton instance in a thread-safe manner using sync.Once.

package main

import (
    "fmt"
    "sync"
    "time"
)

var (
    once sync.Once
    instance *DriverPg
)

// DriverPg represents a PostgreSQL database driver connection.
type DriverPg struct {
    conn string
}

// Connect returns the singleton instance of DriverPg.
func Connect() *DriverPg {
    once.Do(func() {
        instance = &DriverPg{conn: "DriverConnectPostgres"}
    })
    return instance
}

func main() {
    // Simulate a delayed call to Connect.
    go func() {
        time.Sleep(time.Millisecond * 600)
        fmt.Println(*Connect())
    }()

    // Create 100 goroutines.
    for i := 0; i < 100; i++ {
        go func(ix int) {
            time.Sleep(time.Millisecond * 60)
            fmt.Println(ix, " = ", Connect().conn)
        }(i)
    }

    fmt.Scanln()
}
Enter fullscreen mode Exit fullscreen mode

In this example, the DriverPg type represents a database driver connection. The Connect function ensures that the initialization code is executed only once using the once.Do construct from the sync package. This guarantees the thread-safe creation of a single instance of DriverPg.

The code demonstrates that despite multiple concurrent calls to Connect, the initialization logic is executed only once, ensuring that all goroutines share the same instance of DriverPg.

Conclusion 🥂

The Singleton Pattern with sync.Once is a robust and elegant solution for managing single instances across multiple goroutines. By combining the benefits of the traditional Singleton Pattern with thread-safety, this approach enables secure and efficient access to shared resources and configurations.

Reference

Top comments (1)

Collapse
 
aceix profile image
the_aceix

Nice. Another option is to use init()