Já sei que alguns vão falar que não é uma boa idéia, mas eu preciso dessas informações durante toda a *vida* da aplicação.
Então, o que está errado nesse Singleton (bean)?
publicclassUsuarioFormBeanSingleton{privateIntegercodigo;privateStringnome;privateStringsenha;privateIntegernivel;// nivel de acesso de cada usuario/** Creates a new instance of UsuarioFormBeanSingleton */privateUsuarioFormBeanSingleton(){}privatestaticUsuarioFormBeanSingletoninstancia=newUsuarioFormBeanSingleton();publicstaticsynchronizedUsuarioFormBeanSingletongetInstacia(){returngetInstancia();}publicIntegergetCodigo(){returncodigo;}publicvoidsetCodigo(Integercodigo){this.codigo=codigo;}publicStringgetNome(){returnnome;}publicvoidsetNome(Stringnome){this.nome=nome;}publicStringgetSenha(){returnsenha;}publicvoidsetSenha(Stringsenha){this.senha=senha;}publicIntegergetNivel(){returnnivel;}publicvoidsetNivel(Integernivel){this.nivel=nivel;}publicstaticUsuarioFormBeanSingletongetInstancia(){returninstancia;}publicstaticvoidsetInstancia(UsuarioFormBeanSingletonaInstancia){instancia=aInstancia;}}
Um usuário não pode ser singleton : um sistema tem vários usuários
Para quê “UsuarioFormBeanSingleton” e não “Usuario” ?
Vc não precisa de um singleton. Vc precisa de um acesso global.
A sua aplicação é web ? use Session para manter o objeto
Se a sua aplicação é standalone desktop ou em alternativa a 4 use ThreadLocal
O que vc precisa é deixar o usuário acessivel em qualquer Thread então o melhor é ThreadLocal ou uma das suas subclasses.
V
vanzella
Coloque uma variavel para controle no UsuarioFormBeanSingleton
privatestaticintcontador=0;
e Adicione uma validação para limitar o numero de instancias que você quer:
publicstaticUsuarioFormBeanSingletongetInstacia(){if(contador==0){instancia=newUsuarioFormBeanSingleton();contador++;}else{System.out.println("Ja existe uma istancia de UsuarioFormBeanSingleton");}returninstancia;}
J
javer
Pergunta: O que é ThreadLocal?
L
Luca
Olá
Além do que o Sérgio Taborda escreveu, eu completo:
Não use Singletons porque impedem testes unitários
Não use Singletons porque complicam o desacoplamento entre as classes
Não use Singletons porque quase nunca são necessários
Não use Singletons porque causam uma má impressão sobre o tanto que você entende de OO e de coisas tais como injeção de dependências por exemplo.
Básicamente é uma forma de associar variáveis à thread. (Thread vc sabe o que é , né? )
Todo o codigo que vc executa está sendo executado por uma thread. Não sempre pela mesma, mas a cada execução por uma só. Entenda que a thread é omnipresente no seu codigo. Então, se vc associa um objeto à thread vc está associando variáveis omnipresentes ao seu codigo. Ou seja, vc pode atribuir e retornar o seu valor a qualquer momento.
Claro, na prática a coisa não é tão simples. Por isso depende da sua arquitetura. E por isso existe a InheritableThreadLocal. É que as vezes a sua thread se divide em outras. Os dados não passam para essas threads a menos que tenham sido colocados na thread original com InheritableThreadLocal.
Pense nestas classes como um Map omnipresente mas com uma só chave e valor.
Perai, não vamos generalizar, se for assim daqui uns dias vocês estão falando também pra não usar classes internas em swing, “porque causam uma má impressão sobre o tanto que eu entendo de OO”
Vamos lá, o Padrão “Singleton”, “Design Patterns” não foi elaborado pra fuder com as nossas vidas, muito pelo contrario, é uma solução, talves não a mais eficiente, mas basta saber quando, onde e porque utiliza-lo.
Cite 3 casos em que o uso dos Singletons é fundametal em Java e que não se pode obter uma solução melhor com outra alternativa que não ferre os testes unitários.
Cuidado que este artigo contém idéias que não muito boas e que para mim invalidam TODO seu texto.
[]s
Luca
A
aleck
Acho dificil você precisar de singleton como o pessoal já comentou, de qualquer forma, qual a raiz do problema?
Alias, como o sergio comentou, criar um usuario como singleton chega a ser até uma heresia.
V
vanzella
Luca:
Olá
Cite 3 casos em que o uso dos Singletons é fundametal em Java e que não se pode obter uma solução melhor com outra alternativa que não ferre os testes unitários.
Cuidado que este artigo contém idéias que não muito boas e que para mim invalidam TODO seu texto.
[]s
Luca
Não Luca, não estou falando que singleton é a melhor solução sempre, só falei que não podemos generalizar, “nunca usar singleton”, pô a própria Api da sun utiliza esse Pattern, Apache também, entre outras, sera que os arquitetos dessas empresas são todos burros?
M
Marky.Vasconcelos
Até os Renderers do JSF são Singleton
L
Luca
Olá
O problema é que os conceitos MUDARAM. Antigamente ninguém usava injeção de dependências e a prática de testes unitários não era tão obrigatória para selecionar os programadores. Hoje em dia é mais fácil você recomendar fortemente para não usar Singletons do que aturar as conseqüências no projeto de um Singleton mal usado.
E cuidado também que nem sempre os códigos internos do Apache servem de exemplo. Há muito código confuso por lá, mesmo aqueles escritos por não indianos.
[]s
Luca
R
rodrigoallemand
A proposta de utilizar Singleton para reter as informações do usuário foi minha… me desculpem.
Não posso falar pra um iniciante colocar um injeção de dependencia se ele nem entende o que é uma ThreadLocal ainda. Achei que iria enrolar muito o pensamento dele.
Bem, siga as orientações da ThreadLocal ou da Session do sergiotaborda.
Ma bad!
P
peron
Olá,
Falaram de ThreadLocal e fiquei instigado a como se usa então, ao invés do Singleton. Fiz umas buscas na web, e a partir dos exemplos encontrados:
desenvolvi um exemplo, e gostaria de saber se é isso mesmo que sergiotaborda e Luca queriam dizer ao usar InheritedThreadLocal ao inves do puro padrao Singleton.
MyContext.java
packagethreadlocal;importjava.util.Collection;importjava.util.HashMap;importjava.util.Map;/** * */publicclassMyContext{privateMyContext(){//não permite instanciar}privateMap<String,Object>map=newHashMap<String,Object>();protectedstaticInheritableThreadLocalcontext=newInheritableThreadLocal(){@OverrideprotectedObjectinitialValue(){returnnewMyContext();}};publicstaticMyContextgetInstance(){return((MyContext)context.get());}publicCollection<Object>values(){returnmap.values();}publicintsize(){returnmap.size();}publicObjectremove(Stringkey){returnmap.remove(key);}publicObjectput(Stringkey,Objectvalue){returnmap.put(key,value);}publicObjectget(Stringkey){returnmap.get(key);}publicbooleancontainsValue(Stringvalue){returnmap.containsValue(value);}publicbooleancontainsKey(Stringkey){returnmap.containsKey(key);}publicvoidclear(){map.clear();}}
O espirito é esse , mas vc criou logo um map como objeto da thread. :lol:
Assim vc pode guardar o que quiser na thread usando uma só ThreadLocal. Como teste é isso mesmo. Mas eu me referia a usar uma ThreadLocal que não seja um Map e sem usar o mecanismo de singleton. Mas agora bateu a dúvida se dá para fazer sem usar o mecanismo de singleton…
public static MyContext getInstance() {
return ((MyContext) context.get());
}
R
rflprp
Uso singletons para carregar propriedades JMX, não tenho do que reclamar e não vejo forma mais simples de faze-lo.
L
Luca
Olá
O que são propriedades JMX?
Você testa estas classes que usam estas tais “propriedades JMX”?
[]s
Luca
R
rflprp
Propriedades injetadas via JMX.
Sim, consigo testar.
[]'s
R
rodrigoallemand
Eu tb nunca tive dificuldade para testes com Singleton.
Onde, normalmente, eu teria este problema?
L
Luca
Olá
Eu tb nunca tive dificuldade para testes com Singleton.
Onde, normalmente, eu teria este problema?
Como faz testes unitários de uma classe Singleton?Talvez vocês tenham conseguido resolver um problema que muita gente ainda não conseguiu de forma satisfatória.
[]s
Luca
R
rodrigoallemand
Luca:
Como faz testes unitários de uma classe Singleton?Talvez vocês tenham conseguido resolver um problema que muita gente ainda não conseguiu de forma satisfatória.
Ou de repente eu estou fazendo o teste errado por inexperiencia ou falta de visão. E foi por esta duvida que eu lhe perguntei e volto a lhe perguntar: onde há o problema em testar um Singleton?!?
R
rflprp
Luca:
Olá
Eu tb nunca tive dificuldade para testes com Singleton.
Onde, normalmente, eu teria este problema?
Como faz testes unitários de uma classe Singleton?Talvez vocês tenham conseguido resolver um problema que muita gente ainda não conseguiu de forma satisfatória.
[]s
Luca
verifico se ele carrega e armazena as propriedades corretamente, e ele também é utilizado nos unit tests de classes que necessitam de suas propriedades.
isso não é suficiente ?
se não, por favor, dê exemplos práticos.
[]'s
R
rodrigoallemand
Seguindo a mesma linha do Rafael, e refinando mais os testes automatizados, se vc testar, por exemplo, o seu método de negócio que necessite de informações contidas neste Singleton, vc estará indiretamente testando o próprio Singleton, correto?
V
ViniGodoy
Só consigo pensar em uma: Quando você precisa de um programa final de tamanho pequeno (e, portanto, não quer sobrecarregar seu usuário com um framework de DI) para um applet ou uma aplicação mobile. Nesse caso provavelmente a aplicação nem terá muitas threads e classloaders mesmo.
Ainda assim, usar o singleton como um repositório de variáveis globais quase nunca é uma boa idéia. Se puder, fuja dele.
A
Abdon
O problema com a testabilidade dos singletons são a criação de Mocks com teste unitarios. Por exemplo, para testar uma action que faz um consulta em um banco de dados, vc não deve deixar seu DAO se conectar com o banco de dados, pois isto seria um teste de integração e não unitario. A solução para isto é criar um Mock, ou seja, substituir a camada do DAO por um Mock.
Agora imagine que este DAO é um singleton (arg o pior que é tem disto por ai ) Como vc iria fazer para substituir o DAO sem mexer no codigo?
Agora imagine que vc esta usando a injeção de dependencia do spring ou mesmo o conjuto PicoContanier + NanoContainer, para substituir o DAO por um mock bastaria alterar uma simples configuração em um XML.
[]'s
V
ViniGodoy
Um outro detalhe. No livro design patterns, também se referem a código C++.
No C++, algumas característica tornam o uso do singleton mais vantajoso:
C++ não tem um bom mecanismo de reflexão (o que compromete a construção de frameworks de DI);
Não há problemas com multiplos classloaders;
Você elimina a dependencia da classe nos seus headers, o que melhora os tempos de compilação.
Ainda assim, numa aplicação Java comercial comum, não há porque usar singletons hoje em dia. Exceto talvez no caso que eu citei ali (uma restrição forte de equipamento ou tamanho do executável final).
A
Abdon
Vc utiliza um singleton para ler um properties?? é isto que eu estou entendo?
PS: Como eu faço para escrever “Não sei quem disse” em uma citação?
R
rflprp
Sim, tenho uma série de propriedades que são gerenciadas via JMX, e a aplicação tem acesso a elas por meio de singletons, que nada mais são do que javabeans contendo estas propriedades.
Isso faz o acesso a essas propriedades muito simples, por isso não entendo o porque de toda essa alergia a singletons.
[]'s
M
marcosbrandao
ovelha:
PS: Como eu faço para escrever “Não sei quem disse” em uma citação?
Na tag “quote”, coloque o nome: “quote=nomeDeQuemEscreveu”.
Se voce clicar no botão citar, isto vai ser feito automaticamente.
M
marcelo_mococa
também acho estranho o uso de métodos estáticos no FacesContext. Fica muito complicado criar testes para os componentes que acessam o FacesContext.
Apenas reforçando:
cuidado com singletons e métodos estáticos. Os dois dificultam e muito os testes unitários.
V
vanzella
também acho estranho o uso de métodos estáticos no FacesContext. Fica muito complicado criar testes para os componentes que acessam o FacesContext.
Apenas reforçando:
cuidado com singletons e métodos estáticos. Os dois dificultam e muito os testes unitários.
Bom então o problema não é com o padrão singleton e sim com os testes unitarios? o que deve ser encontrado é uma solução pra testes unitarios.
Oras se o banco x não funciona direito com Java, por que vou trocar o banco? vou trocar o java. rsrsr :twisted:
L
Luca
Olá
[]s
Luca
A
aleck
Rafaelprp:
Sim, tenho uma série de propriedades que são gerenciadas via JMX, e a aplicação tem acesso a elas por meio de singletons, que nada mais são do que javabeans contendo estas propriedades.
Isso faz o acesso a essas propriedades muito simples, por isso não entendo o porque de toda essa alergia a singletons.
Bem, isso é tudo que tenho aqui dos meus favoritos, não coloquei algumas paginas como o do shoes pq nao consegui acessar, acho que está off.
Boa leitura pra todos.
M
marcelo_mococa
Não, o problema é que singleton e métodos estáticos aumentam o acoplamento das classes. Quando existe um forte acoplamento, fica difícil criar testes unitários.