Classe com somente uma instancia  XML
Índice dos Fóruns » Java Básico
Autor Mensagem
douglas_vidotto
JavaTeenager
[Avatar]

Membro desde: 12/08/2008 15:43:18
Mensagens: 195
Offline

Olá pessoal, tudo bem? Gostaria de saber se há alguma forma de fazer uma classe em que possa ocorrer somente uma instância dessa e que se alguem de fora da classe fosse usá-la, teria que obrigatoriamente usar essa instancia?

Apareceu essa pergunta no livro use a cabeça Java. Tentei de tudo mas não consegui fazer isso, alguém sabe como faz??

Muito obrigado!
Diego Silveira
Debugger

Membro desde: 12/10/2007 17:15:25
Mensagens: 68
Offline

Esse é o famoso "pattern" ou "antipattern" Singleton.




Diego Silveira
Ciência da Computação - UFU
SCJP 6

[Email] [MSN]
Bruno Laturner
GUJ Expert
[Avatar]

Membro desde: 18/02/2008 16:17:53
Mensagens: 3002
Offline

Um singleton?

A resposta acima foi achada em menos de 5 minutos no google.
The prisoner falls in love with his chains. --E.W. Dijkstra
[WWW]
Diego Silveira
Debugger

Membro desde: 12/10/2007 17:15:25
Mensagens: 68
Offline

Ahh, e para usar faça assim:



Evite o uso excessivo de Singletons, pois hoje é considerado um anti-pattern....Prefira sempre injeção de dependências e inversão de controle (IoC), usando, por exemplo o Spring Framework



Diego Silveira
Ciência da Computação - UFU
SCJP 6

[Email] [MSN]
douglas_vidotto
JavaTeenager
[Avatar]

Membro desde: 12/08/2008 15:43:18
Mensagens: 195
Offline

Hum, entendi, então o segredo é criar uma instancia dentro de um método static da classe e deixar o construtor como private?

Muito obrigado ae! Valews!!

peczenyj
Moderador
[Avatar]

Membro desde: 26/03/2006 23:25:37
Mensagens: 3191
Localização: Rio de Janeiro
Offline

A primeira coisa é vc compreender o pattern Factory.

Para vc ter apenas uma instancia vc não pode usar new, pois isso cria uma nova instância e não ha nada que possamos fazer para evitar. Como instanciar então? Vais ter que ter uma fabrica de objetos, que tem a mesma função pratica do new, porém com outra sintaxe e significado. Vc pedira a fabrica: me de uma instancia dessa classe, e ela retornará o que vc pede. Por isso vc tem métodos getInstance que são estáticos para esse tipo de construção: a sua fabrica ira distribuir referencias de uma unica instancia e uma das formas de vc obter isso é armazenando a instancia que vc quer distribuir como atributo estático. De quebra vc cria um contrutor privado para que ninguem viole a sua classe

http://pacman.blog.br

'Não importa quanto alguém se dedique à tarefa. Ninguém consegue fazer a água da cascata cair para cima.'
[WWW]
Bruno Laturner
GUJ Expert
[Avatar]

Membro desde: 18/02/2008 16:17:53
Mensagens: 3002
Offline

Cuidado ao tentar usar singletons em programas multithread, a implementação do Diego, por exemplo, não é sincronizada a ponto de evitar que ele instancie mais de uma vez.

Nesses casos ou implemente o método com synchronized, ou use aquele que postei.

A resposta acima foi achada em menos de 5 minutos no google.
The prisoner falls in love with his chains. --E.W. Dijkstra
[WWW]
ViniGodoy
Moderador
[Avatar]

Membro desde: 11/12/2006 08:22:01
Mensagens: 20551
Localização: Curitiba/PR
Online

Não entremos em detalhes se o Singleton é ou não um anti-pattern, ou se ele deve ou não ser utilizado.
O importante é entender quais são os problemas dessa solução e quais são suas vantagens. Programar é basicamente tomar decisões baseadas num contexto ou, num jargão mais administrativo, analisar trade-offs.

O singleton, em especial no Java, tem sérios problemas:
1. Não é possível garanti-lo entre vários class-loaders;
2. A solução com lazy initialization (no caso, a primeira postada, onde a variável estática começa com null) não é thread-safe. Poderia ser tornada colocando synchronized no método getInstance(). Esse erro é extremamente comum.
3. É uma classe difícil de se testar, de se substituir por mocks, etc.
4. Uma vez instanciado, ele não pode ser apagado (dá para fazer com WeakReferences, mas isso gera um código relativamente complexo);

Por outro lado:
1. É rápido de escrever;
2. É simples, há pouco overhead de classes, tempo e memória;
3. Não tem dependências externas (você não precisa anexar um framework de IoC para usa-lo).
4. Não depende de reflexão.

Portanto, se você estiver fazendo um software pequeno e embarcado, como no caso de uma aplicação J2ME, o Singleton é uma boa alternativa de design. Software single-threaded, com um único class loader, também se beneficia desse padrão (como é o caso de vários jogos, por exemplo).

Agora, ele se torna inadequado para praticamente todos os softwares comerciais hoje em dia, especialmente os web. Há muita discussão sobre esse padrão ser bom ou não, algumas delas aqui no GUJ (eu e o pcalcado já discutimos aqui sobre isso tb).

This message was edited 1 time. Last update was at 31/10/2008 12:55:39


@ViniGodoy - Lattes

Tem dúvidas de Java? Poste no fórum! Não respondo dúvidas de java via MP!

Ponto V! - Desenvolvimento de Jogos Profissional - @Pontov - Facebook
Projeto Towel - Swing de uma forma inteligente (Novo lar do ObjectTableModel e do Auto-Filtro).

Ei... você está usando DefaultTableModel no seu projeto??
Não faça isso! Veja: http://www.guj.com.br/posts/list/15/199067.java#1001295
[WWW]
Diego Silveira
Debugger

Membro desde: 12/10/2007 17:15:25
Mensagens: 68
Offline

O Bruno está certo.... o meu exemplo não serve para aplicações multi-thread.... nesse caso existem várias opções como utilização de blocos de inicialização, métodos synchronized ou como no exemplo dado, declarar e inicializar em uma mesma linha.



Diego Silveira
Ciência da Computação - UFU
SCJP 6

[Email] [MSN]
thiagofesta
JavaGuru
[Avatar]

Membro desde: 19/12/2007 10:42:11
Mensagens: 233
Offline

Dessa forma que citaram ai, ela pode ser clonada, ou estou enganado?
Como eu poderia bloquear o clone dela?

"É melhor calar-se e deixar que as pessoas pensem que você é tolo, do que falar e acabar com a dúvida"
Abraham Lincoln
[WWW] [Yahoo!] [MSN]
Bruno Laturner
GUJ Expert
[Avatar]

Membro desde: 18/02/2008 16:17:53
Mensagens: 3002
Offline

thiagofesta wrote:Dessa forma que citaram ai, ela pode ser clonada, ou estou enganado?
Como eu poderia bloquear o clone dela?


Faça a classe implementar o Cloneable, e dentro do método clone atire um CloneNotSupportedException

A resposta acima foi achada em menos de 5 minutos no google.
The prisoner falls in love with his chains. --E.W. Dijkstra
[WWW]
thiagofesta
JavaGuru
[Avatar]

Membro desde: 19/12/2007 10:42:11
Mensagens: 233
Offline

Bruno Laturner
Obrigado

Ai sim, implementado tudo o que foi dito, ai sim seria um verdadeiro singleton

"É melhor calar-se e deixar que as pessoas pensem que você é tolo, do que falar e acabar com a dúvida"
Abraham Lincoln
[WWW] [Yahoo!] [MSN]
andre_udi
JavaBaby

Membro desde: 22/06/2006 14:38:22
Mensagens: 88
Offline

ola pessoal,

uma outra solucao interessante pra se fazer um singleton é usar um enum:



ai pra usar:



[]s

Code Monkey
rmarin
JavaEvangelist
[Avatar]

Membro desde: 13/07/2005 09:14:45
Mensagens: 360
Localização: São Paulo
Offline

ViniGodoy wrote:
3. Não tem dependências externas (você não precisa anexar um framework de IoC para usa-lo).
4. Não depende de reflexão.


Mas IoC não depende de um framework pra utilizar, e nunca vi um padrão que precisasse de reflexão.

Roberto Marin
__________________________________________
Odeio auto-nerds!
[WWW]
Fabio "Kym" Nascimento
JavaChild
[Avatar]

Membro desde: 23/08/2008 23:04:58
Mensagens: 124
Offline

Nunca tinha pensado em Singleton com enum, achei a idéia foda =o

O que os experts tem a dizer sobre isso? Singleton com enum? ViniGodoys da vida emitam um parecer!

Por mais que você domine algum tema, sempre há algo a aprender sobre ele.
 
Índice dos Fóruns » Java Básico
Ir para:   
Powered by JForum 2.1.8 © JForum Team