Tenho visto muita discussão sobre o padrão Singleton não ser um bom negócio, algo como as boas e velhas variáveis globais (o “boas” é brincadeira :)).
Em alguns projetos, utilizei o Singleton como um ponto de acesso para dados em cache, mais ou menos assim:
[code]pseudocode:
class ClientesCollection
/* *** Trecho de implementação do Singleton *******/
private static ClientesCollection instance;
public static ClientesCollection getInstance() {
// Se nao existir a instancia, cria nova
if (instance==null)
instance = new ClientesCollection();
// Retorna a instancia.
return instance;
}
public List getList() {
// Retorna uma cópia da lista
}
public List getById(id) {
// Retorna um item especifico
}
/* Outros métodos de busca */
Fim da Classe[/code]
A partir disso, em qualquer ponto do sistema (apresentação, ou camada de negócios) posso obter os dados da
seguinte forma:
List clientes = ClientesCollection.getInstance().getList();
ou
Cliente cliente = ClientesCollection.getInstance().getById(cliId);
etc etc
Como essa lista é mostrada em inúmeras telas e praticamente não sofre alterações no dia-a-dia, a consulta inicial é aproveitada por todo o tempo de vida do aplicativo.
Gostaria de saber a opinião de vocês a respeito desse uso. Estou sendo porco/gambiarreiro :(? É possível melhorar essa implementação?
Você está usando Singleton como variável global. No seu exemplo o problema não é ter mais de um cache, o problema é que os clientes devem usar o mesmo cache.
Como fazer isso? Padrão Registry ou Dependency Injection são as soluções mais comuns.
BTW: seu Singleton tem um problema clássico de concorrência, não vou dizer qual é para que você dê uma procurada
Você está usando Singleton como variável global. No seu exemplo o problema não é ter mais de um cache, o problema é que os clientes devem usar o mesmo cache.[/quote]
Muito triste isso…
Mas por outro lado aprendi um conceito em que eu nunca havia pensado antes: “Todo mundo deve acessar o mesmo” e “Só pode existir um” são coisas diferentes!
O padrão Registry é tão simples que eu achei que ele é que fosse Gambiarra :). Sobre a Dependency Injection, eu ainda não consegui enxergar como posso utiliza-la nesse caso, vou analisar melhor esse pattern.
Não consegui identificar… acredito que seja algo no construtor, pois os demais métodos só fazem leitura então não haverá problemas de concorrência. Mas não consegui encontrar o erro!
Engraçado a dependencia das pessoas com “Conteiner IoC como o Spring”… O Spring, como no exemplo, levanta por default os benas como singleton… até ai nada… ele precisa de um singleton e não de um framework que faz singleton…
Singleton é um padrão… a implementação pode variar… Se sua concorrencia for pouca, seu singleton funciona… se for alta, existem maneiras de melhorar, usando um check duplo, variaveis volatile, etc…
Mas se vc tiver uma aplicação distribuida, esse seu singleton está furado… neste caso, se for web, tente utilizar o context…
Como vc pode ver, são maneiras diferentes para solucionar um problema… Pattern diz respeito a solução de um problema, podendo ter diferentes codificações… e o melhor pattern é o que resolve o seu problema, eficientemente.
boa noite, alguém teria algum exemplo de utilização do padrão Registry, por favor ? ele é usado como uma alternativa para não usar singleton ?
O problema que o pcalcado disse é referente ao método não estar sincronizado ? pois pode acontecer que ele seja chamada por dois processos ao mesmo tempo ? mais como ficaria se acontece isso ? poderia ocorrer duas instancias de um singleton ? (desculpa se estiver falando besteira…rs)
class final ClientesCollection {
private static ClientesCollection instance = new ClientesCollection();
public static ClientesCollection getInstance() {
return instance;
// não precisa de lazy inicilization
// porque na realidade a inicilização vai ser do list de clientes
}
private List clientes = null;
private ClientesCollection() {
// Construtor privado - muito bem
}
public synchronized List getList() {
if (clientes !=null){
clientes = new ClientesDao().getList();
}
// não retorne a copia da lista, retorna uma lista não modificável
// é mais eficiente e mais simples e mais rápido
return new Collections.unmodifiableList(clientes);
}
public Client getById(Object id) {
// Retorna um item especifico
}
}
O que vc fez não é cambiarra mas poderia ser melhor. Não refiro a uma melhor implementação mas a um melhor conceito. Afinal, o que vc quer ?
Quer uma classe que seja um ponto central para acessar a coleção de todos os clientes e tb que possa retornar um só cliente. Vc pode fazer isso sem usar singleton explicitamente. Registry é um nome possivel para a implementação a seguir, embora Repository seja mais apropriado. Porque? Porque Registry implica em registro. Uma parte do codigo registra alguma coisa no registro e outra parte do codigo lê o que foi registrado. Registry é um ponto de encontro entre duas, ou mais, partes do codigo.
Repository não tem a parte do registro. Ninguém registra nada nele. Ele obtém as informações e as disponibiliza.
Eis uma implementação possivel. Note que vc pode procurar por mais coisas que apenas clientes
class final Repositoy{
// sem getInstance
// final impede que seja extendido e private no consturtor impede que seja dado um new
private Repositoy(){}
private static List clientes = null;
private static List fornecedores= null;
public static synchronized List allClients() {
if (clientes !=null){
clientes = new ClientesDao().getList();
}
// retorna uma lista não modificável
return new Collections.unmodifiableList(clientes);
}
public static Client getClient(Object id) {
// Retorna um item especifico
}
public static synchronized List allSuppliers() {
if (fornecedores!=null){
fornecedores= new FornecedoresDao().getList();
}
// retorna uma lista não modificável
return new Collections.unmodifiableList(fornecedores);
}
public static Fornecedor get Fornecedor(Object id) {
// Retorna um item especifico
}
// como adicionar mais clientes
public static synchronized void addClient(Cliente c){
new ClientesDao().insert(c);
clientes = null; // reseta o cache para obrigar a reler do banco.
// apenas para demonstrar que os vários métodos funciona em conjunto
}
}
O uso é ainda mais simples que singleton
List clientes = Repository.allClients();
List fornecedores = Repository.,allSuppliers();
Cliente clienteA = Repository.getClient ("a"); // supondo que 'a' é a chave
Melhor que o singleton porque não precisa ter um singleton para cada entidade e porque com um pouco mais de cuidado e usando generics vc poderá implementar de forma mais curta e simples. Ou implementar métodos mais complexos como
List suppliers = Repositoy.supliersOf (Produto p); // quem fornece este produto ?
List suppliers = Repositoy.clientSuppliers(); // forncedores que são tb clientes
.. etc ..
Usando generics vc pode tb pensar em ter um so DAO, em vez de um para cada entidade.
Quanto a injecção de dependencia vc pode usar um codigo estático que consulta uma fabrica de DAO, ou se tiver apenas um DAO genérico, uma fabrica que retorna a implementação correcta da interface do DAO. ISto porque usar new XXXDAO() é sempre ruim(*).
(*) Do ponto de vista estritamente de design. Pode ser bom se o projeto for pequeno e/ou tiver que ser implementado depressa.
[quote=rodrigoallemand]Engraçado a dependencia das pessoas com “Conteiner IoC como o Spring”… O Spring, como no exemplo, levanta por default os benas como singleton… até ai nada… ele precisa de um singleton e não de um framework que faz singleton…
[/quote]
Não senhor. Se o Spring possui algum Singleton dentro dele eu sinceramente não sei, e não me importa. O que o Spring é para o usuário é uma factory genérica que, por padrão, retorna sempre a mesma instância (isso pdoe ser alterado). Isso é completamente diferente de usar um Singleton na aplicação e mais diferente ainda de usar um Singleton apenas apra poder ‘desfrutar’ de uma variável global no sistema.
O ponto aqui não chegou ao nível de usar Spring ou não, ainda estamos no mundo dos conceitos.
Você está enganado, Singleton (bem implementado) se comporta muito bem com concorrência. Usar variáveis voláteis nem sequer alivia o pior dos problemas de concorrência com Singletons, que é o fato de que no exemplo acima poderem haver mais de um Singleton em memória. Um double check sincronizado evita este problema mas é um senhor desperdício de lock. Existe um meio muito simples e eficaz.
Mas como Singletons são usados apra variáveis globais não há tanto problema, afinal o que se quer é poder acessar uma variável de qualquer lugar do programa, não um objeto que só possa ter uma instância. O padrão trata apenas desta última sentença, ter um objeto que só pode ser instanciado uma vez, por isso usar Singletons quando se quer variáveis globais é uma baita duma gambiarra, infelizmente altamente difundida.
[quote=rodrigoallemand]
Como vc pode ver, são maneiras diferentes para solucionar um problema… Pattern diz respeito a solução de um problema, podendo ter diferentes codificações… e o melhor pattern é o que resolve o seu problema, eficientemente.[/quote]
O problema, Rodrigo, é que me parece que você não leu o problema ao qual este padrão resolve. O problema é ter apenas um bojeto em memória, não acessar recursos.
Teoricamente não. O objetivo do singleton é garantir que não ha forma de ter duas instâncias. E a palavra importante aqui é garantir. Ter certeza. Poder confiar.
Claro que a implementação pode ser mal feita e isso levar a que possam existir duas instancias da classe. Mas isso não significa que ha dois singletons, significa que a implemnetação está errada e não é , na verdade, a implementação de um singleton.
O singleton, como padrão de projeto (design pattern) , como entidade teorica, como simbolo, não permite conceber que existam duas instancias da mesma classe. Por isso que o padrão se chama assim. Single = Unico, Sozinho. Exatamente para deixar claro o objetivo.
O singleton, como implementação, como código, pode permitir que existam duas instâncias. O que ele não pode permitir é que existam simultaneamente do ponto de vista do sistema que o usa.
Se em alguma hipotese, seja porque o código está mal implementado (por exemplo deixando a classe ser extendida), seja porque o método usado para o construir à partida não garante a singularidade (fábricas de injeção, por exemplo) , então, esse código , não é uma implementação do padrão de projeto Singleton. Se não é uma implementação , então , mesmo que tenha sido esse o objetivo original, essa classe não é um singleton.
O padrão Singleton é para classes. É uma forma de implementar uma classe para garantir que não é possível ter , simultaneamente, dois objetos dessa classe.
Este objetivo é diferente de garantir que não existem mais do 1 objeto de uma certa classe. Aqui , estamos preocupados em poupar recursos e não em impedir que se criem mais objetos da classe. Isto é conhecido como Shared Object Pattern (Objeto partilhado) que não é a mesma coisa que Singleton.
Um singleton é um caso especial de shared object. A diferença é que no shared object se usa um so objeto porque se quer. A classe permite criar outros. No singleton, usa um so objeto porque não consigo criar mais nenhum.
Exemplo de Shared Object são os Servelts e os SessionBeans. Um outro caso especial, além do singleton, são implementações de Connection num pool de conexões.
Vou dar a minha opinião sobre o singleton. E aposto que muitos teoricos aqui do GUJ ficarão um tanto decepcionados.
Eu gosto do padrão. E considero ele bastante seguro.
Em primeiro lugar, não estou falando aqui de usar um singleton como variável global, que isso fique bem claro. Mas do uso do Singleton para o que ele foi feito: gerir recursos que realmente são únicos e garantir que determinados objetos tenham somente uma instância.
Agora, sou muito crítico a respeito de designs “perfeitos”. Em primeiro lugar, porque isso não existe. Em segundo, existe diversos custos em designs complexo que, com o tempo, percebi que não só são perda de tempo, como um desperdício pagar por eles. Estamos falando aqui de trade-offs.
Por exemplo, qualquer depency injection decente precisa de um framework para ser bem implementado. Isso é um custo. Ele também está sujeito a erros de runtime, uma vez que implementações serão obtidas por meios reflexivos. O framework também está sujeito a bugs e, se for de terceiros, parabéns, você não terá como prever quando serão corrigidos e ainda corre o risco do frameworks ser abandonado. Por fim, o código fica menos claro, você passa a ter que ler arquivos externos ao .jar. E tudo isso faz parte do custo que estou falando.
Por outro lado, o bom e velho singleton não sofre desses males. Qualquer programador Java pode entende-lo facilmente. Não precisa de nenhum .jar externo.
Em segundo lugar. Os tais “problemas de concorrência” que geram duas instâncias singleton geralmente aconterão se suas threads tentaram acessar uma instância não criada de singleton, simultaneamente, pela primeira vez. O que, na minha opinião, é bastante raro. A razão é até lógica. Na absurda maioria das vezes, acessamos o singleton antes mesmo de haver qualquer concorrência no sistema.
Quanto ao caso dos “multiplos classloaders geram multiplos singletons”. Honestamente, isso não deve ser uma preocupação a menos que você efetivamente use multiplos class loaders. O que é comum em aplicações web e em sistemas distribuídos (mas, no caso de sistemas distribuídos, muitas vezes nem mesmo o dependency injection resolve o problema).
Eu poderia continuar dando mais e mais argumentos. Mas, o que quero frisar aqui é: saiba o que você está fazendo. Se você usa o singleton só porque acha bonito. Rapaz, realmente, procure outras coisas por aí que dizem que são mais bonitas do que singleton.
Agora, se você conhece bem o domínio de sua aplicação, e está escolhendo usar o singleton por ele representar um pattern mais simples, está ciente de suas limitações e das consequências que elas podem te trazer. Muito bem. O singleton será seu amigo e faça ótimo proveito dele. Tenha sempre em mente que design de sistemas é lidar com trade-offs. Que para tudo que você faz haverá vantagens e desvantagens em faze-lo. E que muitas vezes essas desvantagens não são técnicas.
Para quem não conhece muito de C++ e outras linguagens do gênero, vale lembrar que o Singleton foi percebido nesse ambiente.
Em primeiro lugar, há algumas características que tornam o singleton mais interessante fora do Java, e que por isso ele se tornou um pattern tão conhecido:
No C++ não há multiplos class loaders e há maneiras de torna-lo thread-safe;
No C++, o Singleton não precisa ser importado nos header files da classe que o usam. Como ele não é passado por parâmetro, ele pode ser usado diretamente no .cpp. E isso reduz os tempos de compilação;
É muitíssimo seguro usar um objeto singleton. Você evita dores de cabeça com dangling pointers ou memory leaks, já que você não acessa o singleton indiretamente.
[quote=ViniGodoy]Vou dar a minha opinião sobre o singleton. E aposto que muitos teoricos aqui do GUJ ficarão um tanto decepcionados.
[/quote]
Me explica uma coisa: qual o seu conceito de teórico? Teórico é quem estuda sobre sua profissão, lê os livros de referência e aplica as técnicas que são difundidas a anos? Pŕatico é aquele que não quer saber de nada além do básico e mete a mão na massa?
Aqui concordamos…
Antes de prosseguir neste ponto algumas perguntas:
O que é complexidade?
O que é um design perfeito e por que você colocou este termo no assunto?
Não estou dizendo que é o seu caso, mas este tipo de comentário é muito típico quando alguém quer dar uma justificativa para usar uma gambiarra ou um anti-pattern. Frases de efeito como “não tem outro jeito melhor”, “assim é mais simples”, “não dá pra usar OO de verdade”, sem argumentos, só afirmações curtas e drásticas. Para que não fiquemos com a impressão que esse é o caso seria legal sedimentar essa tal complexidade em alguns argumentos.
Ahm? Do jeito que você está colocando é: ou você usa singleton ou usa um framework externo, que simplesmente não é verdade. Ignorando o gerenciamento de dependências facilitado que uma ferramenta desta te dá você pode ter os efeitos com um simples Registry ou um conjunto de Factories, como aliás já foi citado neste tópico.
A propósito, lá em cima você disse que o ponto que defendia não era sobre Singletons como variáveis globais, como a única maneira de comparar um Singleton com IoC é utilizando um método getInscante()-like que emula uma variável global seu texto ficou bem confuso. Afinal, você defende ou não variáveis globais?
Acho que não fui claro lá em cima. Quando mencionei originalmente o problema de concorrência foi apenas uma viso para o autor original, nãoe stava relacionado com o tema Singleton x OO sem variáveis globais (se você parar para ver ot exto vai ver que inicia com um ‘BTW’, que significa 'a propósito).
Ainda assim, se existe (e não existe na maioria dos casos) necessidade do uso de um Singleton você teria um problema sim ao ter duas instâncias. É como ter um Observer e o objeto observado não avisar seus observadores: o padrão foi quebrado.
[quote=ViniGodoy]
Agora, se você conhece bem o domínio de sua aplicação, e está escolhendo usar o singleton por ele representar um pattern mais simples, está ciente de suas limitações e das consequências que elas podem te trazer. Muito bem. O singleton será seu amigo e faça ótimo proveito dele. Tenha sempre em mente que design de sistemas é lidar com trade-offs. Que para tudo que você faz haverá vantagens e desvantagens em faze-lo. E que muitas vezes essas desvantagens não são técnicas.[/quote]
Acho que qualquer um que leia sobre sua profissão (será que ele vira um ‘teórico’ ao pegar um livro?) vai entender que a vida de um desenvolvedor é feita de escolhas que variam com o cenário.
O ponto é que temos um padrão utilizado como anti-pattern amplamente por uma indústria que não se preocupa em coisas simples como gerenciamento de dependências, testabilidade e flexibilidade (muito prejudicadas com o uso do anti-pattern em questão).
Não estava falando de maneira pejorativa ao dizer “teórico”. A teoria é ótima e ela ajuda muito no desenvolvimento.
Mas a teoria procura ser abrangente e, muitas vezes, procura resolver problemas de ocorrência rara. E na prática, realmente, podemos abrir mão de um pouco de purismo para buscar outros benefícios, como um design mais simples.
Bem, a pergunta um é tema de ampla discussão pela humanidade. Aliás, foi até um tanto capiciosa de sua parte, pois você sabe que não há uma resposta concreta. O que temos são definições de complexidade, dadas por diversos autores.
E eu concordo com você. Algumas pessoas podem tentar usar esse comentário para justificar o uso de um anti-pattern, que é o caso de muita gente que faz isso aqui no GUJ.
Mas esse não foi o único argumento que dei e nem de longe quero que fique justificado o uso de uma gambiarra ou de um anti-pattern.
Mas quando um pattern se torna um anti-pattern? Quando ele é usado fora de seu contexto. E é sobre isso que se tratava o meu post. Avaliar corretamente o contexto, não necessariamente justificar um anti-pattern.
Eu estava me referindo justamente a forma como muitos patterns são “vendidos”, especialmente pelos fabricantes de frameworks. Vende-se o pattern como se fosse a solução de todos os problemas. Muitos posts do GUJ usam o mesmo argumento: Troque singleton por dependency injection e durma tranquilo. Não estou falando que é o seu caso, aliás, bem pelo contrário. Gosto muito dos seus posts.
Sim, mas meu post foi sobre trade-offs. Trocar um padrão por outro sempre representa ganhos de um lado e perdas de outro. Usar um framework também. Era isso que eu queria ressaltar. E são esses os trade-offs que devem ser avaliados.
Foi o que ressaltei no exemplo do framework. Você tem que estar ciente que está se baseando em códigos de terceiros e tem que estar ciente das implicações disso. Se o framework usa reflexão, você tem que estar preparado para erros em runtime. É sua responsabilidade, como analista ou projetista de software, avaliar o impacto disso no sistema e o transtorno que isso causa a equipe.
O caso do “simples Registry e de Factories”, é um bom exemplo. Você ainda terá que se incomodar que suas factories sejam thread-safe e operem de maneira semelhante em múltiplos classloaders. Ou você terá o mesmo problema do bom e velho singleton. Daí eu ter dito que, se seu argumento era aquele, você fatalmente recairá num framework que faça isso para você, ou gastará horas desenvolvendo algo que está fora da lógica de seu negócio, ou correrá o risco. Mas deve-se pensar. Essa minha preocupação é relevante? Preciso mesmo garantir thread-safety nesse sistema? Ele roda em múltiplos class loaders?
Sim, eu concordo. Se você tiver duas instâncias de um singleton é um problema sério. Isso foi uma coisa que nunca defendi e até dei algumas situações onde o singleton certamente não se aplica, pois as chances de isso ocorrer são bastante altas.
Esse seu último paragrafo resumiu com maestria tudo o que eu vinha dizendo. Usar corretamente qualquer pattern envolve muito estudo, domínio do problema, entendimento dos requisitos técnicos e não técnicos, uso adequado de soluções provisórias e de longo prazo, organização e uma boa dose de disciplina. Em resumo, é necessário conhecer o pattern, seu impacto sobre todos os fatores que você colocou, dentro do sistema que você está desenvolvendo.
Ao abdicar de uma variável global em forma de Singleton eu não preciso criar factories thread-sfae. A Factory em seu contrato diz que retorna um objeto válido (i.e. invariante satisfeita), não necessariamente que ele retorna sempre um novo objeto ou que retorna sempre o mesmo objeto. Se quisermos manter o mesmo objeto por economia de recursos podemos fazê-los mas como não se trata de um Singleton, não há problema caso mais de um seja criado, é apenas um desperdício de recursos. Caso o desperdício seja um problema pode-se utilizar primiivas bem simples de sincronização.
No caso do Registry é ainda mais simples. O Registry irá guardar as referências em um lugar comum, como um contexto de aplicação, e não nele mesmo. É assim, por exemplo, que JNDI trabalha.
E você não tem este problema com Singletons?
[quote=ViniGodoy]
Esse seu último paragrafo resumiu com maestria tudo o que eu vinha dizendo. Usar corretamente qualquer pattern envolve muito estudo, domínio do problema, entendimento dos requisitos técnicos e não técnicos, uso adequado de soluções provisórias e de longo prazo, organização e uma boa dose de disciplina. Em resumo, é necessário conhecer o pattern, seu impacto sobre todos os fatores que você colocou, dentro do sistema que você está desenvolvendo.[/quote]
Se alguém no GUJ entra perguntando se a tecnologia utilizada em Java para criar aplicações desktop é EJB ou Swing o que você responderia? E se após ser informado que deve buscar por Swing ele avisa que na verdade ele já tem a tela em Delphi e quer algo que fique residente na máquina do usuário e seja acessado pelo Delphi em CORBA?
Casos de exceção semrpe vão acontecer e para estes casos espera-se que o desenvolvedor conheça um mínimo de opções. O problema é nivelar pela exceção.
No caso de gerenciamento de dependências em específico eu realmente nunca ouvi nenhum argumento que faça um Singleton ser mais interessante que uma Factory que retorna o mesmo objeto.
[quote=pcalcado]Ao abdicar de uma variável global em forma de Singleton eu não preciso criar factories thread-sfae. A Factory em seu contrato diz que retorna um objeto válido (i.e. invariante satisfeita), não necessariamente que ele retorna sempre um novo objeto ou que retorna sempre o mesmo objeto. Se quisermos manter o mesmo objeto por economia de recursos podemos fazê-los mas como não se trata de um Singleton, não há problema caso mais de um seja criado, é apenas um desperdício de recursos. Caso o desperdício seja um problema pode-se utilizar primiivas bem simples de sincronização.
[/quote]
No caso de xunxar o singleton para usa-lo como uma variável global, tem toda razão. Mas você pode ter sérios problemas caso o objetivo de usar um singleton seja o original: Você estar controlando um recurso restrito do sistema. Eu não estava falando de usar o singleton como uma variável global, em primeiro lugar. Foi uma das primeiras coisas que ressaltei.
Mas, se seu singleton é o manager de uma conexão socket, que é a única porta de entrada de um determinado servidor, ou se seu singleton atuava como um gerente de memória num profiler, sua factory terá que garantir que as classes tenham acesso a esse recurso único, mesmo entre múltiplas threads. Mas, isso deve ser uma preocupação se seu sistema tiver multiplas threads. E se ele eventualmente um dia utilizar mais de um class loader. E se os malefícios de usar uma outra tecnologia forem inferiores aos malefícios da sua. Trade-offs, trade-offs…
Como eu falei. Se meu sistema não roda em múltiplas threads, não tem vários class loaders, não faz lazy initialization na classe singleton, não. E muitas vezes, posso preferir conviver com isso e ter erros em tempo de compilação quando a classe dependente faltar, ao invés de recorrer a reflexão e ter erros somente em Runtime. Se meu cliente valorizar um código pequeno, ou estiver rodando num hardware com restrições, também posso preferir conviver com os problemas em prol de um requisito mais importante. Novamente, a “moral da história” aqui não é sobre singletons, mas sobre trade-offs.
[quote=pcalcado]
Se alguém no GUJ entra perguntando se a tecnologia utilizada em Java para criar aplicações desktop é EJB ou Swing o que você responderia? E se após ser informado que deve buscar por Swing ele avisa que na verdade ele já tem a tela em Delphi e quer algo que fique residente na máquina do usuário e seja acessado pelo Delphi em CORBA?
Casos de exceção sempre vão acontecer e para estes casos espera-se que o desenvolvedor conheça um mínimo de opções. O problema é nivelar pela exceção.
No caso de gerenciamento de dependências em específico eu realmente nunca ouvi nenhum argumento que faça um Singleton ser mais interessante que uma Factory que retorna o mesmo objeto.[/quote]
Mas é exatamente disso que estou falando: conhecer o domínio do problema. Aqui no GUJ, já vi muita gente criticar o Singleton sem nem mesmo saber do que se tratava a aplicação em questão. Simplesmente postam algo vago como “não use singleton, use depency injection que é melhor”. Por que? Talvez porque tenham lido isso em algum lugar, ou por que seja a propaganda que o framework dele esteja fazendo.
E não porque identificou uma situação (como a do colega deste post) onde havia uma solução mais adequada. E aqui, não estou falando exclusivamente do Singleton, mas de qualquer pattern.
Com a ênfase e urgência que você deu eu imagino que isso seja diário mas sinceramente não lembro de ver uma thread neste fórum onde as pessoas (eu incluso) não fizeram ressalvas antes de sugerir a remoção do Signleton. Ainda que haja, duvido muito que este tipo de postura seja frequente por todos os anos que frequento este site. Acho que você está, novamente, nivelando pela exceção.
Não falei que era regra. E nem dei tanta urgência a esse fato.
Mas há tempos já vinha pensando em postar algo por aqui sobre a importância de se avaliar corretamente o design, de não supervalorizar(ou depreciar) esse ou outro padrão/framework, e de avaliar bem os trade-offs envolvidos.
Talvez só tenha me embaralhado um pouco na hora de passar as idéias para cá.
Citando o Shoes (em algum lugar que eu não copiei)…
Por padrão, o Spring levanta seus Beans como instancias unicas (ou seja, Singletons, conforme descrito em todos os documentos dos autorires). Vc pode passar uma fábrica sua ou setar para que o singleton não seja um singleton (hehehe)…
E sobre padrões, que vc afirma eu não ter lido, aconselho a sair um pouco do mundo dos teóricos e meter a mão na massa mais um pouco… existem problemas (que até invalidam o pattern) no Singleton em ambientes compartilhados…
O intuito do meu post foi ajudar a quem começou a thread… afinal, ninguem respondeu pra ele se o que ele fez estava certo e se funcionava… parece que todos trabalham no mesmo projeto, pra falar que não funciona… vc conhece o contexto do projeto dele? Sabe o que ele realmente precisa pra dizer que o que ele implementou está errado?
Acho que falta um pouco de respeito e um pouco mais de simplicidade nas pessoas desse forum… Afinal isso é um forum, e não uma defesa de tese ou coisa do tipo…
P.S.: E por falar em defesa de tese, quando eu colocar meu tópico sobre minha tese aqui, os arquitetor de plantão vão pirar!!!
[quote=gomesrod]
Gostaria de saber a opinião de vocês a respeito desse uso. Estou sendo porco/gambiarreiro :(? É possível melhorar essa implementação?[/quote]
Leia meu post novamente. Essa foi a pergunta dele e foi respondida.
Quanto á sua afirmação sobre ‘sair do mundo dos teóricos’, é apenas uma bravata de quem ficou sem argumentos. Você não me conhece nem sabe o que eu já fiz ou faço para fazer este tipo de comentário. Se possui este interesse sobre a minha pessoa posso te mandar um link ou quem sabe meu curriculum. Recomendo que se porte como profissional no fórum e use argumentos ao invés de ataques pessoais só levam à descrédito. Ou então simplesmente não responda.
[quote=pcalcado]Quanto á sua afirmação sobre ‘sair do mundo dos teóricos’, é apenas uma bravata de quem ficou sem argumentos. Você não me conhece nem sabe o que eu já fiz ou faço para fazer este tipo de comentário. Se possui este interesse sobre a minha pessoa posso te mandar um link ou quem sabe meu curriculum. Recomendo que se porte como profissional no fórum e use argumentos ao invés de ataques pessoais só levam à descrédito. Ou então simplesmente não responda.
[/quote]
Bem, se este é seu porte profissional, chamar o código dos outros de GAMBIARRA… vc precisa rever seus conceitos…
E não se ofenda… não é nada pessoal… o meu pedido por mais respeito ao post das pessoas foi geral, e não diretamente vc… Se fosse para vc, com certeza, eu colocaris seu nome…
E conhecer vc… bem, eu até conheço… visito o forum, mesmo não 'postando" muito… Sempre que posso, vou às palestras, seminários, etc. Conheço de vc o que eu deveria conhecer… te respeito do mesmo jeito que respeito a todos deste forum… desde quem pede ajuda num for da faculdade quanto a quel tem um problemão num grande cliente…