Olá Pessoal,
Andei lendo algumas referencias sobre ThreadLocal e vi inclusive que existe um plugin para o Vraptor para identificar o uso do mesmo, ou seja não é bem vindo 
Vi que algumas pessoas, inclusive o Guilherme Silveira não recomenda o uso, daí eu pergunto seria o uso indiscriminado, ou uso geral mesmo?
Por exemplo, imagine a situação onde eu tenha que passar dados entre camadas (Exemplo toda alteracao no banco de dados precisa gravar o usuario logado):
Cenário:
Controller -> Service -> DAO
Não vamos entrar em detalhe se eu preciso ou nao da camada Service, vamos assumir que sim eu preciso.
No controller eu vou chamar o Service, método atualizarCliente que por sua vez chama o DAO atualizarCliente
Assinaturas sem uso de ThreadLocal
Service - atualizarCliente(Cliente cliente, Usuario usuario)
DAO - atualizarCliente(Cliente cliente, Usuario usuario)
Se eu utilizar ThreadLocal eu poderia eliminar a passagem do Usuario como parâmetro.
Se formos levar em consideracao poucos metodos nao seria problematico, mas para muitas classes e muitos metodos acaba poluindo. O que acham?
Qual seria uma solucao mais elegante sem o uso de ThreadLocal?
Obrigado
“Poluindo” é o seu jeito de usar um ThreadLocal (que é só para evitar passar uma lista grande de parâmetros). Há usos mais nobres para um ThreadLocal que esse que você quer fazer.
Evite usar esse tipo de coisas (passar parâmetros implícitos), isso deixa a testabilidade de seu programa muito ruim.
Se acha que está passando sempre os mesmos 10 parâmetros, crie uma classe simples, que encapsule esses 10 parâmetros, e passe uma instância dessa classe.
[quote]“Poluindo” é o seu jeito de usar um ThreadLocal (que é só para evitar passar uma lista grande de parâmetros). Há usos mais nobres para um ThreadLocal que esse que você quer fazer.
Evite usar esse tipo de coisas (passar parâmetros implícitos), isso deixa a testabilidade de seu programa muito ruim.
Se acha que está passando sempre os mesmos 10 parâmetros, crie uma classe simples, que encapsule esses 10 parâmetros, e passe uma instância dessa classe. [/quote]
Mas e se a necessidade dele for um tipo de “auditoria” em que todo serviço que altere uma propriedade de um ou varios tipos de entidade, deva-se inserir um registro no banco com o usuário logado? Creio que não seria elegante passar por parametro o usuário logado em todos os serviços.
E se além do usuário, fosse necessário saber por qual tela do sistema que a entidade foi alterada?
Sei que está fugindo um pouco do tópico, mas teria uma maneira mais elegante de se fazer isso?
Qualquer coisa usada de forma errada não é recomendada…mas no seu caso (pelo seu descritivo) é ThreadLocal mesmo.
Pode usar sim…tome cuidado com a limpeza, uma vez que os container web reutilizam as threads.
[quote=entanglement]“Poluindo” é o seu jeito de usar um ThreadLocal (que é só para evitar passar uma lista grande de parâmetros). Há usos mais nobres para um ThreadLocal que esse que você quer fazer.
Evite usar esse tipo de coisas (passar parâmetros implícitos), isso deixa a testabilidade de seu programa muito ruim.
Se acha que está passando sempre os mesmos 10 parâmetros, crie uma classe simples, que encapsule esses 10 parâmetros, e passe uma instância dessa classe. [/quote]
Bom, na verdade não vejo apenas como “que é só para evitar passar uma lista grande de parâmetros”, se for uma solução baseada no ThreadLocal eu poderia colocar de forma genérica a tarefa de recuperar o usuário ou ainda como foi citado pelo emannuel, informar outros dados para auditoria etc. No caso citado pela emannuel, como você acha que poderia ser uma solução menos “verbosa”?
Quanto ao uso de parâmetros implicitos acho que nem sempre é algo ruim, veja por exemplo o conceito de parametros implicitos da linguagem Scala (Apenas uma referencia).
[quote=FernandoFranzini]Qualquer coisa usada de forma errada não é recomendada…mas no seu caso (pelo seu descritivo) é ThreadLocal mesmo.
Pode usar sim…tome cuidado com a limpeza, uma vez que os container web reutilizam as threads.
[/quote]
Realmente esse é um ponto que merece atenção quando se executa o codigo dentro do container Web.