• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

magician

[Java/JSP] Padrão Singleton

4 mensagens neste tópico

O Singleton é um dos padrões de projecto mais simples. Ele é usado quando for necessária a existência de apenas uma instância de uma classe. Foi apresentado no GoF como um padrão de criação, por lidar com a criação de objectos.

Segundo o GoF para uma classe ser um singleton, deve-se garantir que haverá apenas uma instância na aplicação e que deve-se fornecer um ponto de acesso à mesma. Mas como garantir que haverá apenas uma instância? É de conhecimento comum que, para criar uma instância de uma classe, devemos chamar o seu construtor. Assim, para resolvermos o problema, devemos restringir o acesso ao construtor, tornando-o um método privado. Em seguida, deve-se utilizar um método público que faça o controle da instanciação, de modo que ela só possa ser feita uma vez. A Figura 1 mostra o diagrama de classes do singleton:

img-01.JPG

[ Figura 1: Diagrama de Classes do Singleton. ]

A implementação mais comum do singleton  pode ser vista no código apresentado em seguida.

public class Singleton {


   private static Singleton instance;

   private Singleton() {

   }

   public static Singleton getInstance() {
      if (instance == null)
         instance = new Singleton();
      return instance;
   }
}

[Código 1]

O diagrama de classes da Figura 1 e o Código 1 acima mostram apenas o necessário para a instanciação de singleton. Obviamente, a classe deve conter outros atributos e métodos.

A Figura 2 mostra um diagrama de sequências que representa o processo de criação de um singleton. Quando um objecto chama o singleton pela primeira vez, é realizada a instanciação da classe. Os demais acessos irão utilizar a instância já criada.

img-02.JPG

[ Figura 2: Diagrama de Seqüências de um Singleton. ]

O Código 1  pode ser problemático em ambientes multi-threaded, ou seja, ele não é uma solução thread-safe. Se uma thread  chamar o método getInstance() e for interrompida antes de realizar a instanciação, uma outra thread  poderá chamar o método e realizar a instanciação. Neste caso, duas instâncias serão construídas, o que fere os requisitos do singleton . Uma solução para este problema seria utilizar o atributo synchronized  em getInstance(), como visto no Código 2 , para que uma outra thread  não possa acessá-lo até que a thread  que o acessou pela primeira vez tenha terminado de fazê-lo.

public class Singleton {


   private static Singleton instance;

   private Singleton() {

   }

   public static synchronized Singleton getInstance() {
      if (instance == null)
         instance = new Singleton();
      return instance;
   }
}

[Código 2]

O problema com o synchronized  é que a sincronização é bastante dispendiosa. Estima-se que métodos sincronizados sejam cerca de cem vezes mais lentos que métodos não sincronizados. Uma alternativa simples, rápida e thread-safe  é a instanciação do singleton  assim que ele for declarado. Como podemos ver no Código 3.

public class Singleton {


   private static Singleton instance = new Singleton();

   private Singleton() {

   }

   public static Singleton getInstance() {
      return instance;
   }
}

[Código 3]

Conclusões:

Além de ser um dos padrões mais simples, o singleton  é também um dos mais criticados e mal usados. Uma situação em que realmente é necessário que exista apenas uma instância de uma classe é difícil e o seu uso pode levar a muitos problemas. O uso abusivo de singletons  leva a soluções onde a dependência entre objetos é muito forte e a testabilidade é fraca. Um outro problema é que os singletons dificultam o hot redeploy por permanecerem em cache, bloqueando mudanças de configuração. Por esses e outros problemas, deve-se ter cuidado com o uso abusivo de singletons.

Fonte : www.jeebrasil.com.br

Adaptado por mim :P

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Por mais que leia, nunca percebi qual é a utilidade do singleton nem tão pouco por que motivo é que tem um nome.  Ou porquê chamar a isso um padrão. Alguem me esclarece estas dúvidas existenciais.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

É um padrão porque define um comportamento base, e não uma implementação, um padrão nunca define como se implementa, apenas a estrutura comum. É algo obtido através da prática onde, por se ter verificado que se implementavam várias vezes coisas muito similares, apenas com pormenores de implementação diferentes, e sempre com os mesmos objectivos, se extraiu um padrão. Por isso se chama padrão :)

Singleton, porque o objectivo deste padrão é criar um objecto único dentro de um determinado ambiente e garantir que esse objecto é único.

A utilidade, como todos os padrões, depende do objectivo concreto que se pretende. Claro que os exemplos que te posso dar podem ser feitos sem o padrão, mas o padrão oferece alguma segurança e garantias. O que podes reter é que se precisares de um objecto que seja único num sistema, então estarás a usar o padrão Singleton, e seja qual for a forma como implementares o código, não será muito diferente de outras implementações.

Mas neste caso, o Singleton, é um padrão cuja utilidade é complicada de perceber, e podem ser apontados mais problemas que vantagens.

Posso tentar dar um exemplo, num programa que estou a desenvolver tenho um objecto que serve de entrada ao sistema, não tenho uma classe principal, mas tenho uma classe que tem todos os métodos de acesso à aplicação, é um objecto que preciso que seja único e que não seja instanciado por mais ninguém, devido à natureza do sistema a única forma de garantir que o objecto é único é usar o padrão Singleton e impedir que outra pessoa ou sistema crie uma cópia do objecto ou crie um outro objecto. Neste caso o objecto poderia ser instanciado se não proibisse explicitamente a sua instanciação o que iria provocar a existência de duas instâncias de um objecto que devia ser único.

Se calhar compliquei mais que simplifiquei :), mas para resumir, a única coisa que o padrão indica é uma forma de garantir que um objecto é instanciado apenas uma vez.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora