DESIGN PATTERNS – SINGLETON

O padrão de projeto Singleton tem o objetivo de garantir que uma classe tenha no máximo uma única instância durante todo o ciclo de vida do aplicativo.

Veja o seu diagrama de classes e código Java que implementam o padrão:

Figura 1 – Singleton
public class Singleton {

  private static Singleton instancia;

  private Singleton() {
  }

  public static synchronized Singleton obterInstancia() {
    if (instancia == null) {
      instancia = new Singleton();
    }
    return instancia;
  }

}

Listagem 1 – Singleton

Os elementos participantes desse padrão são:

Singleton

É uma classe. Ela tem no máximo uma única instância durante todo o ciclo de vida do aplicativo. Seu atributo privado de nome instancia, do tipo Singleton, armazena a única instância — depois de criada, da classe Singleton. O construtor dessa classe é privado, protegido de acesso externo. Mas por que o construtor deve ser privado? Por um simples motivo: não permitir instanciar a classe “do seu lado de fora”. E ai vem outra pergunta: então como ela é instanciada? A resposta está no método obterInstancia(). Esse método é responsável por criar e retornar a instância única de Singleton. Ele verifica se a classe já possui uma instância ativa (no atributo instancia). Se ela já tem uma instância ativa, o método apenas a retorna; se ainda não tem uma instância ativa, o método cria uma instância, atribui ela ao atributo instancia e a retorna. É interessante que o método obterInstancia() seja seguro em relação a threads (thread-safe), pois caso contrário podem ocorrer anomalias. O principal problema que pode ocorrer é uma thread sacana sobrescrever a instância criada por outra thread.

Resolvendo um Problema de Projeto Utilizando o Padrão de Projeto Singleton

O padrão de projeto Singleton é relativamente simples. Na minha opinião, ele é o mais simples entre os padrões GoF (“Gang of Four”). É possível imaginar aplicações práticas utilizando esse padrão logo após um primeiro contato. Para exemplificar uma aplicação prática desse padrão, imagine o seguinte problema:

Em um projeto de aplicativo, há uma classe responsável por fornecer informações que são necessárias em vários pontos do aplicativo. Como ter uma única instância dessa classe, e fornecer acesso a essa instância, sem a necessidade de repassá-la e armazená-la em vários lugares? A resposta claro que você já sabe… aplicar o padrão de projeto Singleton.

Veja o diagrama de classes e código Java que implementam a solução:

Figura 2 – Singleton
public class SistemaSingleton {

  private static SistemaSingleton instancia;

  private String usuarioAutenticado;

  private Singleton() {
  }

  public static synchronized SistemaSingleton obterInstancia() {
    if (instancia == null) {
      instancia = new Singleton();
    }
    return instancia;
  }

  public String getUsuarioAutenticado() {
    return this.usuarioAutenticado;
  }

  public void setUsuarioAutenticado(String usuarioAutenticado) {
    this.usuarioAutenticado = usuarioAutenticado;
  }

}

Listagem 2 – Singleton

Os elementos participantes dessa solução, são:

SistemaSingleton

É uma classe. Ela contém um atributo de instância privado do tipo String e de nome usuarioAutenticado, que armazena o usuário autenticado na aplicação. Para a leitura e escrita desse atributo, existem dois métodos de instância: getUsuarioAutenticado() e setUsuarioAutenticado(String usuarioAutenticado). Até aqui ela é uma simples classe, mas aplicando os elementos restantes de acordo com o diagrama acima, ela se torna uma classe Singleton. Agora para sua utilização basta chamar

SistemaSingleton.obterInstancia().setUsuarioAutenticado(usuarioAutenticado);

Listagem 3 – Singleton

ou

usuarioAutenticado = SistemaSingleton.obterInstancia().getUsuarioAutenticado();

Listagem 4 – Singleton

em qualquer ponto do aplicativo sem a necessidade de criar uma instância manualmente e armazená-la em vários lugares. Esse trabalho de criar uma instância e controlar o seu armazenamento fica por conta da classe Singleton!

Considerações Finais

Utilizar Singleton, evita a criação excessiva de elementos estáticos em uma aplicação. Seu uso é fácil de aplicar e simples de entender, pois envolve apenas uma classe. Lembre-se de avaliar se o ambiente é multi-thread para tornar o método obterInstancia() seguro em relação a threads (thread-safe).

Um grande abraço!

Por VICTOR FERRER PETRELLI

Postado em: 08 de maio de 2015

Confira outros artigos do nosso blog

REST não é JSON

21 de agosto de 2017

Bruno Sofiato

[Webinar] Profile de aplicações Java com Oracle Mission Control e Flight Recorder

24 de julho de 2017

Danival Calegari

Criando Mocks de serviços REST com SoapUI

27 de junho de 2017

Monise Costa

JavaScript 6: diferença entre var, let e const

09 de maio de 2017

Otávio Felipe do Prado

Deixe seu comentário