Last active
October 27, 2021 10:06
-
-
Save euclid1990/d59d9301ecb6f4a2b0d08d00f4820faf to your computer and use it in GitHub Desktop.
Go - Singleton Pattern
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"sync" | |
) | |
var ( | |
doOnce sync.Once | |
doLock = &sync.Mutex{} | |
instance *db | |
) | |
type db struct { | |
Connection string | |
} | |
func setInstance(connection string) { | |
instance = &db{Connection: connection} | |
fmt.Println("Singleton instance has been created.") | |
} | |
func (d *db) GetConnection() string { | |
return d.Connection | |
} | |
func GetInstanceByDoOnce(connection string) *db { | |
doOnce.Do(func() { | |
setInstance(connection) | |
}) | |
return instance | |
} | |
func GetInstanceByDoLock(connection string) *db { | |
if instance == nil { | |
doLock.Lock() | |
defer doLock.Unlock() | |
setInstance(connection)package main | |
import ( | |
"fmt" | |
"io" | |
"os" | |
"sync" | |
) | |
var ( | |
instance *db | |
doOnce sync.Once | |
doLock = &sync.Mutex{} | |
out io.Writer = os.Stdout | |
) | |
type db struct { | |
Connection string | |
} | |
func setInstance(connection string) { | |
instance = &db{Connection: connection} | |
fmt.Fprintln(out, "Singleton instance has been created.") | |
} | |
func (d *db) GetConnection() string { | |
return d.Connection | |
} | |
func GetInstanceByDoOnce(connection string) *db { | |
doOnce.Do(func() { | |
setInstance(connection) | |
}) | |
return instance | |
} | |
func GetInstanceByDoLock(connection string) *db { | |
if instance == nil { | |
doLock.Lock() | |
defer doLock.Unlock() | |
setInstance(connection) | |
} | |
return instance | |
} | |
func main() { | |
connectionString := "[email protected]:3306/main-schema" | |
GetInstanceByDoOnce(connectionString) | |
GetInstanceByDoLock(connectionString) | |
} | |
} | |
return instance | |
} | |
func main() { | |
connectionString := "[email protected]:3306/main-schema" | |
GetInstanceByDoOnce(connectionString) | |
GetInstanceByDoLock(connectionString) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"bytes" | |
"testing" | |
"github.com/stretchr/testify/assert" | |
"github.com/stretchr/testify/suite" | |
) | |
type SingletonTestSuite struct { | |
suite.Suite | |
} | |
func (suite *SingletonTestSuite) SetupTest() { | |
instance = nil | |
} | |
func (suite *SingletonTestSuite) TestDbGetConnection() { | |
connectionString := "[email protected]:3306/main-schema" | |
db := &db{Connection: connectionString} | |
assert.Equal(suite.T(), connectionString, db.GetConnection()) | |
} | |
func (suite *SingletonTestSuite) TestSetInstance() { | |
bak := out | |
out = new(bytes.Buffer) | |
defer func() { out = bak }() | |
setInstance("[email protected]:3306/main-schema") | |
assert.Equal(suite.T(), "Singleton instance has been created.\n", out.(*bytes.Buffer).String()) | |
} | |
func (suite *SingletonTestSuite) TestGetInstanceByDoOnce() { | |
bak := out | |
out = new(bytes.Buffer) | |
defer func() { out = bak }() | |
connectionStringFirst := "[email protected]:3306/main-schema-do-one-first" | |
connectionStringSecond := "[email protected]:3306/main-schema-do-one-second" | |
instanceFirst := GetInstanceByDoOnce(connectionStringFirst) | |
instanceSecond := GetInstanceByDoOnce(connectionStringSecond) | |
assert.Equal(suite.T(), connectionStringFirst, instanceFirst.GetConnection()) | |
assert.Equal(suite.T(), connectionStringFirst, instanceSecond.GetConnection()) | |
} | |
func (suite *SingletonTestSuite) TestGetInstanceByDoLock() { | |
bak := out | |
out = new(bytes.Buffer) | |
defer func() { out = bak }() | |
connectionStringFirst := "[email protected]:3306/main-schema-do-lock-first" | |
connectionStringSecond := "[email protected]:3306/main-schema-do-lock-second" | |
instanceFirst := GetInstanceByDoLock(connectionStringFirst) | |
instanceSecond := GetInstanceByDoLock(connectionStringSecond) | |
assert.Equal(suite.T(), connectionStringFirst, instanceFirst.GetConnection()) | |
assert.Equal(suite.T(), connectionStringFirst, instanceSecond.GetConnection()) | |
} | |
func TestSingletonTestSuite(t *testing.T) { | |
suite.Run(t, new(SingletonTestSuite)) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment