Pergunta

Como implementar um Singleton design pattern) na linguagem de programação go?

Foi útil?

Solução

Deixando de lado o argumento de se implementar ou não o padrão de singleton é uma boa idéia, aqui está uma possível implementação:

package singleton

type single struct {
        O interface{};
}

var instantiated *single = nil

func New() *single {
        if instantiated == nil {
                instantiated = new(single);
        }
        return instantiated;
}

single e instantiated são privados, mas New() é público. Assim, você não pode instanciar diretamente single sem passar New(), e rastreia o número de instanciações com o booleano privado instantiated. Ajustar a definição de single provar.

No entanto, como vários outros têm notado, isso não é seguro para fios, a menos que você esteja apenas inicializando seu singleton em init(). Uma abordagem melhor seria alavancar sync.Once Para fazer o trabalho duro para você:

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
}

Veja também, a sugestão de Hasan J de apenas pensar em um pacote Como um singleton. E, finalmente, considere o que os outros estão sugerindo: que os singletons geralmente são um indicador de uma implementação problemática.

Outras dicas

Antes de tentar encontrar uma maneira de dobrar o Ir à sua vontade, você pode querer dar uma olhada em alguns artigos:

Em resumo, ao longo do tempo as pessoas têm encontrado gestações únicas para ser menos do que o ideal e, imho especialmente se você está tentando fazer qualquer desenvolvimento orientado a testes:em muitos níveis, e eles são praticamente tão ruim como variáveis globais.

[termo de responsabilidade:Eu sei que não é um rigoroso resposta para a sua pergunta, mas ele realmente é relevante]

Basta colocar as variáveis e funções em nível de pacote.

Veja também a pergunta semelhante: Como fazer um singleton em Python

Eu acho que em um mundo simultâneo precisamos estar um pouco mais conscientes de que essas linhas não são executadas atomicamente:

if instantiated == nil {
    instantiated = new(single);
}

Eu seguiria a sugestão de @marketer e usaria o pacote "Sync"

import "sync"

type MySingleton struct {

}

var _init_ctx sync.Once 
var _instance *MySingleton

func New() * MySingleton {
     _init_ctx.Do( func () { _instance = new(MySingleton) }  )
     return _instance 
}

A melhor abordagem será:

 package singleton

 import "sync"

 type singleton struct {
 }

 var instance *singleton
 var once sync.Once

 func GetInstance() *singleton {
     once.Do(func() {
         instance = &singleton{}
     })
     return instance
 }

Você deveria ler isso Link

Você pode fazer a inicialização usando o Uma vez pacote:

Isso garantirá que seus métodos inits sejam chamados apenas uma vez.

Basta ter uma única instância estática, final, constante, global e em toda a aplicação do objeto que você deseja.

No entanto, isso contradiz o paradigma OO. Seu uso deve ser limitado a primitivos e objetos imutáveis, não a objetos mutáveis.

Você deve estar ciente de que Once.Do é sério sobre a execução do código apenas uma vez. Isso significa que o código é sempre executado apenas uma vez, mesmo que possa ter entrado em pânico:

a partir de https://golang.org/pkg/sync/#once.do

Se f (nota: a lógica única) entrar em pânico, considere retornar; Chamadas futuras do retorno sem ligar f.

Em vez disso, usei mutexes para garantir a inicialização exclusiva de uma variável de configuração global para superar essa restrição:

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top