Jump to content
Sign in to follow this  
magician

Padrão Singleton

Recommended Posts

magician

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


I haven’t lost my mind; it’s backed up on DVD somewhere!

Share this post


Link to post
Share on other sites
pedrotuga

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.

Share this post


Link to post
Share on other sites
Knitter

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

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.