SingletonSingleton é um padrão de projeto de software (do inglês Design Pattern). Este padrão garante a existência de apenas uma instância de uma classe, mantendo um ponto global de acesso ao seu objeto. Nota linguística: O termo vem do significado em inglês para um conjunto (entidade matemática) que contenha apenas um elemento.[1] Alguns projetos necessitam que algumas classes tenham apenas uma instância. Por exemplo, em uma aplicação que precisa de uma infraestrutura de log de dados, pode-se implementar uma classe no padrão singleton. Desta forma existe apenas um objeto responsável pelo log em toda a aplicação que é acessível unicamente através da classe singleton. Onde UsarQuando você necessita de somente uma instância da classe, por exemplo, a conexão com banco de dados, vamos supor que você terá que chamar diversas vezes a conexão com o banco de dados em um código na mesma execução, se você instanciar toda vez a classe de banco, haverá grande perda de desempenho, assim usando o padrão singleton, é garantida que nesta execução será instânciada a classe somente uma vez. Lembrando que este pattern é considerado por muitos desenvolvedores um antipattern, então, cuidado onde for utilizá-lo. Como fazer a implementação do Singleton1. Deixar o construtor privado, pois assim ninguém deve conseguir instanciar a classe, apenas o próprio Singleton. 2. Criar um atributo privado e estático do mesmo tipo da classe (instance). Algumas linguagens não tipadas não irão precisar do tipo, caso do PHP, por exemplo. 3. Método getInstance() é o principal ponto da classe. Ele verifica se a variável instance já foi iniciada, caso não tenha sido, ele faz sua criação pela primeira e única vez. 4. Para fazer a conexão, devemos chamar o getInstance da seguinte forma: ClasseSingleton.getInstance(). ExemplosEm Perl 5Segue um exemplo em Perl 5 de uma das formas de implementar uma classe Singleton com a orientação a objetos nativa: package Singleton {
our $_instance;
# construtor
sub instance {
my $class = shift;
# constrói $_instance caso seja undef
$_instance = bless {}, $class unless $_instance;
return $_instance
}
}
Em Python 2.7Segue um exemplo em Python 2.7 de uma das formas de implementar uma classe Singleton (Utilizando o __new__): class Singleton(object):
_instance = None
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = super(Singleton, cls).__new__(
cls, *args, **kwargs)
return cls._instance
Em C++Segue um exemplo em C++ da implementação de uma classe Singleton: class MyClass
{
private:
// atributo estático da "instância única"
static MyClass* instance = 0;
// construtor privado: não pode ser utilizado fora da classe
MyClass() {}
public:
// função-membro que retorna sempre a mesma instância do objeto
static MyClass& getInstance()
{
if (!instance) instance = new MyClass();
return *instance;
}
};
Em JavaA partir da versão 1.5 do Java, a melhor abordagem utilizada para a definição de tipos Singleton é com a utilização de tipos Enum, tal como mencionado por Joshua Bloch em seu livro "Java Efetivo Segunda Edição Revisada". Observe um exemplo: public class SingletonDuplaVerificacao {
private static SingletonDuplaVerificacao instance;
private SingletonDuplaVerificacao() {}
public static SingletonDuplaVerificacao getInstance() {
if(instance == null) {
synchronized(SingletonDuplaVerificacao.class) {
if(instance == null) {
instance = new SingletonDuplaVerificacao();
}
}
}
return instance;
}
}
Como usar:
1: Deixar o construtor privado, assim evitando qualquer criar um NEW.
2: Atributos privados e Estatico do mesmo tipo da classe instance
3: Metodo getInstance();
Em um dos parágrafos do Item 3 do livro de Joshua Bloch, ele diz: "Essa abordagem é funcionalmente equivalente à abordagem de campo público, exceto por ser mais concisa, fornecer o mecanismo de serialização facilmente e fornecer uma garantia sólida contra a instanciação múltipla, mesmo no caso de serialização sofisticada ou ataques de reflexão. Embora ela ainda tenha que ser amplamente adotada, um tipo enum com apenas um elemento é a melhor maneira de implementar um singleton." Em C#Segue um exemplo em C# da implementação de uma classe Singleton: using System;
public class MyClass
{
private static MyClass instance;
private MyClass() {}
public static MyClass Instance
{
get
{
if (instance == null)
{
instance = new MyClass();
}
return instance;
}
}
}
Em DelphiAbaixo segue um exemplo de como implementar uma classe Singleton: interface
type
TSingleton= class
private
class var FInstance: TSingleton;
class function GetInstance: TSingleton; static;
public
class property Instance : TSingleton read GetInstance;
end;
implementation
class function TSingleton.GetInstance: TSingleton;
begin
If FInstance = nil Then
FInstance := TSingleton.Create();//objeto instanciado através do Finstance
Result := FInstance;//retorna o objeto
end;
Em PHPAviso importante: Singleton em PHP é considerado um anti-pattern por causa da life cycle request/response que aplicações PHP normalmente utilizam. <?php
namespace DesignPattern\AntiPattern;
class Singleton
{
private static $instance;
/**
* Evita que a classe seja instanciada publicamente.
*
* @return void
* /
private function __construct()
{
}
/**
* Evita que a classe seja clonada.
*
* @return void
* /
private function __clone()
{
}
/**
* Método unserialize do tipo privado para prevenir a
* desserialização da instância dessa classe.
*
* @return void
* /
private function __wakeup()
{
}
/**
* Testa se há instância definida na propriedade,
* caso sim, a classe não será instanciada novamente.
*
* @return DesignPattern\AntiPattern\Singleton
* /
public static function getInstance()
{
if (!isset(self::$instance)) {
self::$instance = new self;
}
return self::$instance;
}
}
Em Rubyrequire 'singleton'
class Foobar
include Singleton
end
Em VB.NET Public Class MyClass
Private Shared _instancia As MyClass
Private Shared objetoSincronia As New Object
Private Sub New()
End Sub
Public Shared Function getInstancia() As MyClass
If _instancia Is Nothing Then
SyncLock objetoSincronia
If _instancia Is Nothing Then _instancia = New MyClass
End SyncLock
End If
Return _instancia
End Function
End Class
Em ActionScript 3package{
public class ExemploSingleton {
private static var instance:ExemploSingleton;
public function ExemploSingleton(enforcer:SingletonEnforcer) : void {
if (enforcer == null)
throw new Error("Só pode haver uma instância de ExemploSingleton");
}
public static function getInstance() : ExemploSingleton {
if (instance == null)
instance = new ExemploSingleton( new SingletonEnforcer );
return instance;
}
}
}
//Para bloquear o acesso ao constructor.
class SingletonEnforcer {
}
Em C# (utilizando Generics)public sealed class GenericSingleton<T> where T : class, new()
{
private static T _instance;
public static T GetInstance()
{
lock (typeof(T))
{
if (_instance == null)
_instance = new T();
return _instance;
}
}
}
// Teste do padrão Singleton
public class Car { public int Color { get; set; } }
public class Person { public string Name { get; set; } }
class Program
{
static void Main(string[] args)
{
Car car = GenericSingleton<Car>.GetInstance();
car.Color = 1;
Person per = GenericSingleton<Person>.GetInstance();
per.Name = "John";
Car car2 = GenericSingleton<Car>.GetInstance();
car.Color = 2;
}
}
Obs: Esta solução não impede a criação de múltiplas instâncias das classes Em KotlinSegue um exemplo de Singleton em Kotlin. public object Singleton {
public fun facaAlgumaCoisa() {
//Aqui será feito alguma coisa legal
}
}
// O singleton é usado assim:
Singleton.facaAlgumaCoisa()
Em TypescriptSegue um exemplo de Singleton em Typescript. class MyClass {
private static instance: MyClass | undefined;
private constructor() {}
public static getInstance(): MyClass {
if (!this.instance) {
this.instance = new MyClass();
return this.instance;
} else {
return this.instance;
}
}
}
Benefícios
Contras
Referências
Ver também |