Pergunta

public class MySingletonClass
{
  public MySingletonClass()
  {
    _mySingletonObj = Instance();
  }

  public static MySingletonClass Instance()
  {
    if (_mySingletonObj  == null)
    {
      lock (typeof(lockObject))
      {
        if (_mySingletonObj  == null)
          _mySingletonObj  = new MySingletonClass();
      }
    }
    return _mySingletonObj ;
  }
}

MySingletonClass _myObj = new MySingletonClass();

Este ato como singleton com construtores públicos ..?

Graças

Foi útil?

Solução

Não, não é um singleton - qualquer um pode criar várias instâncias do mesmo. (Deixando de lado o problema de estouro de pilha que já foi levantada, eo fato de que você está usando double-checked locking insegura.)

Uma das características distintivas de um tipo singleton é que ele impede mais de uma instância de si mesmo nunca ser construída.

A partir da wikipedia Singleton artigo Padrão :

Em engenharia de software, o singleton padrão é um padrão de design que é utilizado para restringir de um instanciação classe para um objeto.

A partir Ward Cunningham repositório padrão :

A Singleton é a combinação de dois propriedades essenciais:

  • Certifique-se de uma classe tem apenas uma instância
  • Fornecer um ponto global de acesso a ele

É evidente que o seu singleton não cumprir estas duas definições.

Ver o meu Singleton artigo para implementações reais.

Outras dicas

O código conforme publicado não funciona como um singleton, devido ao construtor público, mas para além disso, há inúmeras falhas e problemas com o código:

  • construtor público chama Instância, que chama construtor público, que chama Instância, que chama ..... estouro de pilha iminente
  • construtor público retorna um novo objeto de cada vez que é chamado, você não pode substituir o resultado retornado com a mesma referência de objeto em cima dos pedidos subsequentes. Em outras palavras, construtor público nos intervalos únicos o padrão.
  • Você não deve vazar seus objetos de bloqueio, que em seu caso, você bloqueio sobre o tipo de um objeto. Não faça isso, bloquear vez em um objeto particular.

Aqui está uma versão corrigida do seu código:

public class MySingletonClass
{
  private readonly object _mySingletonLock = new object();
  private volatile MySingletonClass _mySingletonObj;

  private MySingletonClass()
  {
    // normal initialization, do not call Instance()
  }

  public static MySingletonClass Instance()
  {
    if (_mySingletonObj == null)
    {
      lock (_mySingletonLock)
      {
        if (_mySingletonObj  == null)
          _mySingletonObj = new MySingletonClass();
      }
    }
    return _mySingletonObj;
  }
}

MySingletonClass _myObj = MySingletonClass.Instance();

Confira a seção de código .NET otimizados na Dofactory . Isto tem IMO a melhor implementação. Também confira o site para outras implementações de padrão de projeto em C #.

O construtor deve ser privado

Em vez de bloqueá-lo, você também pode tentar criar um estático readonly Singleton ...

public sealed class Singleton
{
    private static readonly Singleton instance = new Singleton();

    static Singleton()
    {
    }

    private Singleton()
    {
    }

    /// <summary>
    /// The public Instance property to use
    /// </summary>
    public static Singleton Instance
    {
        get { return instance; }
    }
}

A essência do Singleton é fornecer:

  • exatamente uma instância da classe em todo o sistema;
  • simples acesso a ele.

A implementação de Singleton baseada na criação de uma classe com um método (ou propriedade em .NET) que cria uma instância desta classe se se não existe ainda. O construtor da classe deve ser privado para evitar que outras formas de inicialização. Também Singleton deve ser cuidadosamente usada em aplicações multi-threaded porque em um ponto de tempo, as duas roscas podem criar dois casos diferentes (o que viola padrão Singleton).

Mais detalhes e exemplos que você pode encontrar aqui.

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