Go Single casePattern explanation and code examples.
Single caseIt is a creative design pattern that allows you to ensure that a class has only one instance and provides a global node to access that instance.
Singletons have the same advantages and disadvantages as global variables. Although they are very useful, they can destroy the modularity of the code.
In some other contexts, you cannot use a singleton-dependent class. You will also have to use a singleton class. In most cases, this restriction occurs when creating unit tests.
Concept example
Typically, singleton instances are created when the structure is first initialized. To achieve this, we define agetInstance
Get the instance method. This method will be responsible for creating and returning singleton instances. After creation, each callgetInstance
The same singleton instance will be returned.
Is there anything to pay attention to in coroutines? Whenever multiple coroutines want to access an instance, the singleton structure must return the same instance. Because of this, the implementation of singleton design patterns is prone to errors. The example below shows the correct way to create a singleton.
Some notable points:
- There will be
nil
Check, make suresingleInstance
Singleton instances are empty at the beginning. This is to prevent every callgetInstance
All methods are used to perform huge locking operations. If the inspection fails, it meanssingleInstance
The field has been populated. -
singleInstance
The structure will be created during locking. - There will be another one after the lock is obtained
nil
examine. This is to ensure that even if multiple coroutines bypass the first check, only one single instance can be created. Otherwise, all coroutines will create their own singleton structure instances.
:Single case
package main import ( "fmt" "sync" ) var lock = &{} type single struct { } var singleInstance *single func getInstance() *single { if singleInstance == nil { () defer () if singleInstance == nil { ("Creating single instance now.") singleInstance = &single{} } else { ("Single instance already created.") } } else { ("Single instance already created.") } return singleInstance }
:Client code
package main import ( "fmt" ) func main() { for i := 0; i < 30; i++ { go getInstance() } // Scanln is similar to Scan, but stops scanning at a newline and // after the final item there must be a newline or EOF. () }
:Execution results
Creating single instance now.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Another example
-
init
function
We caninit
Create a singleton instance in the function. This only applies when the instance's early initialization work has been determined.init
The function will only be called once in each file in the package, so we can be sure that it will only create one instance.
Only once will be performed. You can view the following code:
:Single case
package main import ( "fmt" "sync" ) var once type single struct { } var singleInstance *single func getInstance() *single { if singleInstance == nil { ( func() { ("Creating single instance now.") singleInstance = &single{} }) } else { ("Single instance already created.") } return singleInstance }
:Client code
package main import ( "fmt" ) func main() { for i := 0; i < 30; i++ { go getInstance() } // Scanln is similar to Scan, but stops scanning at a newline and // after the final item there must be a newline or EOF. () }
:Execution results
Creating single instance now.
Single instance already created.
Single instance already created.
This is the article about the singleton pattern explanation and code examples of Go design pattern. For more related Go singleton pattern content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!