Padrão Singleton com construtor público
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
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.