Diagrama UML de uma classe singleton.

Singleton é 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 Usar

editar

Quando 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 Singleton

editar

1. 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().

Exemplos

editar

Em Perl 5

editar

Segue 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.7

editar

Segue 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++

editar

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 Java

editar

A 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#

editar

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 Delphi

editar

Abaixo 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 PHP

editar

Aviso 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  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 Ruby

editar
require 'singleton'

class Foobar
    include Singleton
end

Em VB.NET

editar
 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 3

editar
package{
 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)

editar
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 Car e Person. Como a classe genérica GenericSingleton obriga que as classes passadas no parâmetro T tenham um construtor público, é possível criar instâncias em qualquer trecho de código através de construções do tipo: Car car3 = new Car();.

Em Kotlin

editar

Segue 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 Typescript

editar

Segue 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

editar
  • Permite o controle sobre como e quando os clientes acessam a instância.
  • Várias classes singleton podem obedecer uma mesma interface, permitindo assim que um singleton em particular seja escolhido para trabalhar com uma determinada aplicação em tempo de execução.
  • Com apenas uma implementação interna do singleton pode-se fazer com que o singleton crie um número controlado de instâncias.
  • É mais flexível que métodos estáticos por permitir o polimorfismo.

Contras

editar
  • Acoplamento: Usando Singleton você estará acoplando o seu código em uma implementação estática e específica. Isso faz o seu código dependente dessa classe e impede, por exemplo, criar mocks em testes unitários.
  • Escopo: Se você por alguma razão decidir que para determinado componente da aplicação você precisa de outra implementação terá que alterar manualmente todas as classes.
  • Falsa segurança: No java, por exemplo, não existe uma classe apenas por JVM. O conceito de carregamento de classes em java é feito por ClassLoader.

Referências

  1. «singleton - definition of singleton in English from the Oxford dictionary - definition 1.4». www.oxforddictionaries.com. Consultado em 24 de agosto de 2016 

Ver também

editar

📚 Artikel Terkait di Wikipedia

Lista de exemplos de código PHP

'Privado'; echo $this->atributoPrivado; } } class ClasseFilha extends ClassePai { public $atributoPublico; public function imprimeFilho() { $this->atributoProtegido

Controvérsia sobre alimentos geneticamente modificados

Nuclei from Mice Fed on Genetically Modified Soybean.». Cell Structure and Function (em inglês). 27 (4): 173–180. ISSN 0386-7196. PMID 12441651. doi:10.1247/csf

Factory method

End Class Public Class MinhaAplicacao Inherits Aplicacao Public Overrides Function criaDocumento() As Documento Return New MeuDocumento End Function End

Cidadão de primeira classe

tradução literal de First-class Citizen: Cidadão de Primeira Classe (também tipo, objeto, entidade ou valor de primeira classe) em uma determinada linguagem

Aves

significados, veja Ave (desambiguação) ou Aves (desambiguação). Aves são uma classe de seres vivos vertebrados endotérmicos caracterizada pela presença de penas

Yasutaka Ihara

Congresso Internacional de Matemáticos em Nice (1970: Non abelian class fields over function fields in special cases). On Congruence Monodromy Problems, Mathematical

Abstract factory

Function criarBotao() As Botao Return New BotaoQt End Function End Class Public MustInherit Class Botao Public MustOverride Sub desenhar() End Class Public

Python

heranças múltiplas. Uma classe é definida com class nome:, e o código seguinte é a composição dos atributos. Todos os métodos da classe recebem uma referência