{"id":652,"date":"2019-11-23T17:24:20","date_gmt":"2019-11-23T17:24:20","guid":{"rendered":"https:\/\/golangbyexamples.com\/?p=652"},"modified":"2019-12-27T16:38:07","modified_gmt":"2019-12-27T16:38:07","slug":"singleton-design-pattern-go","status":"publish","type":"post","link":"https:\/\/golangbyexamples.com\/singleton-design-pattern-go\/","title":{"rendered":"Singleton Design Pattern in Go (Golang)"},"content":{"rendered":"\n

Note: Interested in understanding how all other design patterns can be implemented in GO. Please see this full reference – All Design Patterns in Go (Golang)<\/a><\/p>\n\n\n\n

Introduction:<\/strong><\/p>\n\n\n\n

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. This single instance is called a singleton object. Some of the cases where the singleton object is applicable:
<\/p>\n\n\n\n

  1. DB instance<\/strong> – we only want to create only one instance of DB object and that instance will be used throughout the application. <\/li>
  2. Logger instance<\/strong> – again only one instance of the logger should be created and it should be used throughout the application.<\/li><\/ol>\n\n\n\n

    The singleton instance is created when the struct is first initialized.  Usually, there is getInstance() method defined on the struct for which only one instance needs to be created. Once created then the same singleton instance is returned every time by the getInstance()<\/strong>.<\/p>\n\n\n\n


    In GO we have goroutines. Hence the singleton struct should return the same instance whenever multiple goroutines are trying to access that instance. It is very easy to get a singleton design pattern wrong. The below code illustrates the right way to create a singleton object. <\/p>\n\n\n\n

    var lock = &sync.Mutex{}\n\ntype single struct {\n}\n\nvar singleInstance *single\n\nfunc getInstance() *single {\n    if singleInstance == nil {\n        lock.Lock()\n        defer lock.Unlock()\n        if singleInstance == nil {\n            fmt.Println(\"Creting Single Instance Now\")\n            singleInstance = &single{}\n        } else {\n            fmt.Println(\"Single Instance already created-1\")\n        }\n    } else {\n        fmt.Println(\"Single Instance already created-2\")\n    }\n    return singleInstance\n}<\/code><\/pre>\n\n\n\n

    Above code ensures that only one instance of the single struct is created. Some point worth noting. 
    <\/p>\n\n\n\n

    1. There is a check at the start for nil singleInstance<\/strong>. This is to prevent the expensive lock operations every time getinstance()<\/strong> method is called. If this check fails then it means that singleInstance<\/strong> is already created<\/li>
    2. The singleInstance<\/strong> is created inside the lock.<\/li>
    3. There is another check for nil singleIinstance<\/strong> after the lock is acquired. This is to make sure that if more than one goroutine bypass the first check then only one goroutine is able to create the singleton instance otherwise each of the goroutine will create its own instance of the single<\/strong> struct.<\/li><\/ol>\n\n\n\n

      Here is the full code<\/p>\n\n\n\n

      single.go<\/strong><\/p>\n\n\n\n

      package main\n\nimport (\n    \"fmt\"\n    \"sync\"\n)\n\nvar lock = &sync.Mutex{}\n\ntype single struct {\n}\n\nvar singleInstance *single\n\nfunc getInstance() *single {\n    if singleInstance == nil {\n        lock.Lock()\n        defer lock.Unlock()\n        if singleInstance == nil {\n            fmt.Println(\"Creting Single Instance Now\")\n            singleInstance = &single{}\n        } else {\n            fmt.Println(\"Single Instance already created-1\")\n        }\n    } else {\n        fmt.Println(\"Single Instance already created-2\")\n    }\n    return singleInstance\n}<\/code><\/pre>\n\n\n\n

      main.go<\/strong><\/p>\n\n\n\n

      package main\n\nimport (\n    \"fmt\"\n)\n\nfunc main() {\n    for i := 0; i < 100; i++ {\n        go getInstance()\n    }\n    \/\/ Scanln is similar to Scan, but stops scanning at a newline and\n    \/\/ after the final item there must be a newline or EOF.\n    fmt.Scanln()\n}<\/code><\/pre>\n\n\n\n

      Output:<\/strong><\/p>\n\n\n\n

      Creting Single Instance Now\nSingle Instance already created-1\nSingle Instance already created-1\nSingle Instance already created-1\nSingle Instance already created-1\nSingle Instance already created-1\nSingle Instance already created-1\nSingle Instance already created-1\nSingle Instance already created-1\nSingle Instance already created-1\nSingle Instance already created-2\nSingle Instance already created-2\nSingle Instance already created-2\nSingle Instance already created-2\nSingle Instance already created-2\nSingle Instance already created-2\nSingle Instance already created-2\nSingle Instance already created-1\nSingle Instance already created-1\nSingle Instance already created-1\nSingle Instance already created-2\nSingle Instance already created-1\nSingle Instance already created-1\nSingle Instance already created-1\nSingle Instance already created-1\nSingle Instance already created-1\nSingle Instance already created-1\nSingle Instance already created-1\nSingle Instance already created-1\nSingle Instance already created-1<\/code><\/pre>\n\n\n\n

      Note:<\/strong><\/p>\n\n\n\n

      • There is one output of \"Creating Single Instance Now\" <\/strong>meaning only one goroutine was able to create a single instance.<\/li>
      • There are a couple of outputs of \"Single Instance already created-1\"<\/strong> meaning that some of the goroutines found the value of singleInstance as nil in the first check and bypassed that.<\/li>
      • There are couple of output of \"Single Instance already created-2\" <\/strong>meaning by the time they reached the single instance was already created and they could not bypass the first if check<\/li><\/ul>\n\n\n\n

        Other methods of creating a singleton object in Go<\/strong><\/p>\n\n\n\n

        • init() function<\/strong><\/li><\/ul>\n\n\n\n

          We can create a single instance inside the init function. This is only applicable if the early initialization of the object is ok. The init function is only called once per file in a package,  so we can be sure that only a single instance will be created.
          <\/p>\n\n\n\n

          • sync.Once<\/strong><\/li><\/ul>\n\n\n\n

            The sync.Once will only perform the operation only once. See below code<\/p>\n\n\n\n

            single.go<\/strong><\/p>\n\n\n\n

            var once sync.Once\n\ntype single struct {\n}\n\nvar singleInstance *single\n\nfunc getInstance() *single {\n    if singleInstance == nil {\n        once.Do(\n            func() {\n                fmt.Println(\"Creting Single Instance Now\")\n                singleInstance = &single{}\n            })\n    } else {\n        fmt.Println(\"Single Instance already created-2\")\n    }\n    return singleInstance\n}<\/code><\/pre>\n\n\n\n

            Output:<\/strong><\/p>\n\n\n\n

            Creting Single Instance Now\nSingle Instance already created-2\nSingle Instance already created-2<\/code><\/pre>\n\n\n\n
            • There is one output of \"Creating Single Instance Now\" <\/strong>meaning only one goroutine was able to create the single instance<\/li>
            • There are couple of output of \"Single Instance already created-2\" <\/strong>meaning by the time they reached the single instance was already created and they could not bypass the first if check<\/li><\/ul>\n","protected":false},"excerpt":{"rendered":"

              Note: Interested in understanding how all other design patterns can be implemented in GO. Please see this full reference – All Design Patterns in Go (Golang) Introduction: Singleton Design Pattern is a…<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"spay_email":"","footnotes":"","jetpack_publicize_message":"","jetpack_is_tweetstorm":false},"categories":[1],"tags":[80,79],"class_list":["post-652","post","type-post","status-publish","format-standard","hentry","category-tech","tag-singleton","tag-singleton-design-pattern-in-golang"],"yoast_head":"\nSingleton Design Pattern in Go (Golang) - Welcome To Golang By Example<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/golangbyexamples.com\/singleton-design-pattern-go\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Singleton Design Pattern in Go (Golang) - Welcome To Golang By Example\" \/>\n<meta property=\"og:description\" content=\"Note: Interested in understanding how all other design patterns can be implemented in GO. Please see this full reference – All Design Patterns in Go (Golang) Introduction: Singleton Design Pattern is a...\" \/>\n<meta property=\"og:url\" content=\"https:\/\/golangbyexamples.com\/singleton-design-pattern-go\/\" \/>\n<meta property=\"og:site_name\" content=\"Welcome To Golang By Example\" \/>\n<meta property=\"article:published_time\" content=\"2019-11-23T17:24:20+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2019-12-27T16:38:07+00:00\" \/>\n<meta name=\"author\" content=\"admin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"admin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/golangbyexamples.com\/singleton-design-pattern-go\/\",\"url\":\"https:\/\/golangbyexamples.com\/singleton-design-pattern-go\/\",\"name\":\"Singleton Design Pattern in Go (Golang) - Welcome To Golang By Example\",\"isPartOf\":{\"@id\":\"https:\/\/golangbyexamples.com\/#website\"},\"datePublished\":\"2019-11-23T17:24:20+00:00\",\"dateModified\":\"2019-12-27T16:38:07+00:00\",\"author\":{\"@id\":\"https:\/\/golangbyexamples.com\/#\/schema\/person\/8833ea7638dafd763cb1db6c0ca4576f\"},\"breadcrumb\":{\"@id\":\"https:\/\/golangbyexamples.com\/singleton-design-pattern-go\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/golangbyexamples.com\/singleton-design-pattern-go\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/golangbyexamples.com\/singleton-design-pattern-go\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/golangbyexamples.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Singleton Design Pattern in Go (Golang)\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/golangbyexamples.com\/#website\",\"url\":\"https:\/\/golangbyexamples.com\/\",\"name\":\"Welcome To Golang By Example\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/golangbyexamples.com\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/golangbyexamples.com\/#\/schema\/person\/8833ea7638dafd763cb1db6c0ca4576f\",\"name\":\"admin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/golangbyexamples.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/?s=96&d=mm&r=g\",\"caption\":\"admin\"},\"url\":\"https:\/\/golangbyexamples.com\/author\/admin\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Singleton Design Pattern in Go (Golang) - Welcome To Golang By Example","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/golangbyexamples.com\/singleton-design-pattern-go\/","og_locale":"en_US","og_type":"article","og_title":"Singleton Design Pattern in Go (Golang) - Welcome To Golang By Example","og_description":"Note: Interested in understanding how all other design patterns can be implemented in GO. Please see this full reference – All Design Patterns in Go (Golang) Introduction: Singleton Design Pattern is a...","og_url":"https:\/\/golangbyexamples.com\/singleton-design-pattern-go\/","og_site_name":"Welcome To Golang By Example","article_published_time":"2019-11-23T17:24:20+00:00","article_modified_time":"2019-12-27T16:38:07+00:00","author":"admin","twitter_card":"summary_large_image","twitter_misc":{"Written by":"admin","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/golangbyexamples.com\/singleton-design-pattern-go\/","url":"https:\/\/golangbyexamples.com\/singleton-design-pattern-go\/","name":"Singleton Design Pattern in Go (Golang) - Welcome To Golang By Example","isPartOf":{"@id":"https:\/\/golangbyexamples.com\/#website"},"datePublished":"2019-11-23T17:24:20+00:00","dateModified":"2019-12-27T16:38:07+00:00","author":{"@id":"https:\/\/golangbyexamples.com\/#\/schema\/person\/8833ea7638dafd763cb1db6c0ca4576f"},"breadcrumb":{"@id":"https:\/\/golangbyexamples.com\/singleton-design-pattern-go\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/golangbyexamples.com\/singleton-design-pattern-go\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/golangbyexamples.com\/singleton-design-pattern-go\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/golangbyexamples.com\/"},{"@type":"ListItem","position":2,"name":"Singleton Design Pattern in Go (Golang)"}]},{"@type":"WebSite","@id":"https:\/\/golangbyexamples.com\/#website","url":"https:\/\/golangbyexamples.com\/","name":"Welcome To Golang By Example","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/golangbyexamples.com\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/golangbyexamples.com\/#\/schema\/person\/8833ea7638dafd763cb1db6c0ca4576f","name":"admin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/golangbyexamples.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/?s=96&d=mm&r=g","caption":"admin"},"url":"https:\/\/golangbyexamples.com\/author\/admin\/"}]}},"jetpack_featured_media_url":"","jetpack_publicize_connections":[],"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/paOs1b-aw","amp_validity":null,"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/golangbyexamples.com\/wp-json\/wp\/v2\/posts\/652","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/golangbyexamples.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/golangbyexamples.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/golangbyexamples.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/golangbyexamples.com\/wp-json\/wp\/v2\/comments?post=652"}],"version-history":[{"count":5,"href":"https:\/\/golangbyexamples.com\/wp-json\/wp\/v2\/posts\/652\/revisions"}],"predecessor-version":[{"id":1027,"href":"https:\/\/golangbyexamples.com\/wp-json\/wp\/v2\/posts\/652\/revisions\/1027"}],"wp:attachment":[{"href":"https:\/\/golangbyexamples.com\/wp-json\/wp\/v2\/media?parent=652"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/golangbyexamples.com\/wp-json\/wp\/v2\/categories?post=652"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/golangbyexamples.com\/wp-json\/wp\/v2\/tags?post=652"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}