Continuaçãod as discussões sobre JavaBeans deste topico.
Super JavaBeans: Milagre ou Maldição?
78 Respostas
Como lingaugem de script, é bem razoável. Ah não, não é não. Use outra linguagem de script, até ASP fica melhor que isso.
Esta prática subutiliza o poder OO do Java. Se alguém quer fazer isso, ótimo, cada umt em sua cabeça, ams se você não quer diexar os benefícios dos objetos de lado, comece a tentar modelar sistemas sem beans.
Para começar, sua JSP deve única e exclusivamente gerar HTML, preferencialmente baseada nos atributos em escopo de request (sem acessar outros escopos ou processar nada).
Processamentod e regras de negócio? POJOs (google ou fórum). Processamentod e request HTTP? Servlets.
Não estou falando que esta implementação é incorreta, pelo contrário
fundamentalmente é perfeita, mas se fomos analisar, muitos conceitos puros do OO são quebrados por causa de limitações tecnológicas.
Já pra começar temos esses getters e setters. São ridículos…
Fora um montão de coisas…
Me refiro a sistema distribuído como sistemas que tem componentes residentes em várias máquinas.(EJB, Web Services, CORBA, RMI, etc)
Um fator a se considerar é o número de chamadas na rede.
Outro fator é centralização das regras de negócio. Imagine você colocar as regras de negócio em objetos que estão localmente em várias máquinas diferentes. Iria-se no mínimo criar uma redundancia, fora a dificuldade de mudanças.
Então ao meu modo de ver é ideal o uso dos beans apenas para coleta e fornecimento de dados para os serviços, sendo eles EJB, Web Services, RMI ,etc. E esses fazendo ponte com as regras de negócio.
Temos que pensar sim no que pode acontecer com um sistema, isso garante a extensão da vida útil do mesmo.
Senão para que a gente se preocuparia com esses DAOs, Patterns e monte de coisas. Não existem apenas para garantir a reusabilidade e facilidade de manutenção.
Aí, Shoes, então???
Essa forma de javabeans é bom ou ruim? Aquilo é OO?
Pra gravar tudo no banco de dados eu vou gravando e retorno tudo em boolean, entende? Se for false o retorno da gravação eu faço:
this.status = false;
this.msgErro = javaBeanBD.getMsgErro();
e na tela de exibição eu faço
if (!cliente.gravaCliente())
{
msgErro = cliente.getMsgErro();
}
Na verdade eu faço isso não só com o jsp, mas tb com tudo, inclusive nos programas superwaba… eu imaginava que este era um bom uso da OO.
@editado = enquanto eu perguntava isso as respostas de cima eram dadas 
Ja fiz de duas formas:
String nome = usuario.getNome(); e String nome = usuario.nome;Pelo código ali então, eu deveria ter métodos que validassem meus atributos dentro do meu Bean?
Não, o ponto é: esqueça os beans e pense em objetos.
Meu mobjeto usuáriod eve sair mostrando a senha dele para todo mundo aí? No cotnexto do meu exemplo, não. A senah é secreta do usuário, então o que ele deve ter é um método para validar uma senha passada. Imagina se eu faço um getSenha que retorna uma senha criptografada, se você tentar usar este para pegar o valor e compará-lo em seguida, você vai ter que criptografá-lo.
Isso não é responsabildiade da classe cliente, mas sim da que oferece o serviço. Imagine o cneário:
class CaixaEletronico{
public void autenticar(String senha){...}
public void setUsuarioAtual(){...}
}
class Usuario{
String getSenha(){...}
}
Lembrando que você deveria modelar seu sistema próximo do mundo real, qual a melhor solução que alguém pdoeria implementar?
Sim, muitos nem estão repsentes em Java ou em outras linguagens. mas os quesão possíveis devem (deveriam IMHO) ser utilizados.
Na verdade, essa limitação foi superada com metadados.
Continua genérico 
Tá, você leu sobre o DTO? Porque, sabe, o padrão é justamente sobre isso 
Se você for se preocupar com tudo que pode acotnecer, vai cair no erro semelhante a o de um modelo em cascata.
DAO e blablabla serve para fazer a arquitetura flexível qeu te falei.
Acho que vou falar besteira mas vai lá:
Neste caso acima a classe Usuario então deveria ter um método que já retornasse a senha criptografada, e a classe CaixaEletronico passaria este método como parâmetro do método autenticar()?
Assim:
public class Usuario{
public String retornaSenha(){
...criptografa a senha
...retorna a senha
}
}
public class CaixaEletronico{
public boolean autentica(usuario.retornaSenha){...}
}
Eu não chamaria aquilo sequer de a forma correta de usar JSP, ams tem gente que discorda. Aquilo é JASP - JSP ahcando que é ASP.
Pra gravar tudo no banco de dados eu vou gravando e retorno tudo em boolean, entende? Se for false o retorno da gravação eu faço:Na verdade eu faço isso não só com o jsp, mas tb com tudo, inclusive nos programas superwaba… eu imaginava que este era um bom uso da OO.
@editado = enquanto eu perguntava isso as respostas de cima eram dadas ;)
Entre a apresentação e a persistência fica sua camada de negócios, use ela 
Pra gravar tudo no banco de dados eu vou gravando e retorno tudo em boolean, entende? Se for false o retorno da gravação eu faço:this.status = false; this.msgErro = javaBeanBD.getMsgErro();e na tela de exibição eu faço
if (!cliente.gravaCliente()) { msgErro = cliente.getMsgErro(); }Na verdade eu faço isso não só com o jsp, mas tb com tudo, inclusive nos programas superwaba… eu imaginava que este era um bom uso da OO.
@editado = enquanto eu perguntava isso as respostas de cima eram dadas ;)
Nossa, isso da uma quantidade de if enorme nao?
:shock:
Neste caso acima a classe Usuario então deveria ter um método que já retornasse a senha criptografada, e a classe CaixaEletronico passaria este método como parâmetro do método autenticar()?
Segundo esse racicío, eu tenho duas classes fazendo o mesmo trabalho (criptografando uma senha). Don’t repeat yourself 
todo mundo tem um if…
A interface grafica tem um if, o cliente tem if… todo mundo tem if
Cara, ainda nao tinha percebido… mas tem muito mesmo. 
Entre a apresentação e a persistência fica sua camada de negócios, use ela ;)
Assim, esse assunto tá sendo coisa nova pra mim.
O que teria na camada de negócios??? Seria onde eu trataria o cliente, o vendedor, o produto… é isso??? Como separar cada elemento?
Acho que eu to lesado hoje, não to notando a duplicação. A classe Usuario criptografa a senha, e a classe CaixaEletronico autentica(verificando se ela é válida ou não).
Eu acho que os javabeans devem ser usados para representar as entidades em niveis granulares.
ex:
class Usuario
{
private String nome;
private String senha;
// getters and setters
}
classe Login
{
public void autenticar(Usuario usuario) throws RegraException
{
// regra de negocios
/// o error vai em forma de execption
}
}
Aqui você tem desacoplamento, a classe login pode existir em apenas um lugar e posso ter a classe Usuario em vários. se eu mudar a implementação da autenticação mudo só em um lugar.
É OO puro, não , mais é funcional…
Felipe, pense assim…
Você é cotnratado para cosntruir um gerenciador de barraquinha de sorvete. Qual sua primeira atitude? pensar se é Hibernate/JSP/Velocity/Struts/WebWork ? Começou mal 
Quando um cliente vira pra você dizendo: eu quero isso, isso e aquilo, ele te dá uma série de problemas que você precisa resolver através de um sistema. Vamos deixar a metodologia de lado (por agora) e pensar que você vai conseguir resolver tudo em uma versão só do software.
Pegue a lsita de problemas (conhecidos também nas rodas de samba como "requisitos"0 e os resolva utilizando apenas classes normais e testes unitários, aplciando padrões e toda a parafernalha OO de sempre, mas sem se preocupar com apresentação ou persistência.
Pronto, você tem sua camada de negócio 
Se seu mdoelo for bom (e isso varia com experiência) você não vai ter que alterar muita coisa para colcoar isso em DAO, Hibernate, Entity Bean (ops, esse sim), Struts (Também), qualquer coisa…
Eu acho que os javabeans devem ser usados para representar as entidades em niveis granulares.
ex:... classe Login { public void autenticar(Usuario usuario) throws RegraException { // regra de negocios /// o error vai em forma de execption } }
Ok, mas login não deveria ser um método? Um “login” é uma entidade?
Questão bem subjetiva essa. Eu te garanto que em ASp, VB, COBOL, BASIC… vais er bem funcional também. A questão é: OO vale a pena? Achoq eu então isso dá outro tópico…
todo mundo tem um if…A interface grafica tem um if, o cliente tem if… todo mundo tem if
Cara, ainda nao tinha percebido… mas tem muito mesmo. :(
Se tu fosse fazer aqueles testezinho de OO onde nao se pode usar if tu taria morto neh. 
Por que nao tratar estes erros na camanda de modelo de maneira adequada?
]['s
opa :!:
Então a camada de negócios é tudo aquilo que vc tem entre a apresentação e o armazenamento… tranquilo isso. Se vc faz assim ou assado na regra de negócios depende do padrão que usa, né? Mas era justamente dentro da regra de negócios que eu queria ter uma idéia de uma boa implementação entende?? Queria saber como fazer aplicação da OO ali dentro.
Eu sei que vc vai me mandar ler um livro ou googlar, tudo bem eu vou, mas antes eu gostaria de saber o básico disso, pra nao ler bobagem e sair mudando os sistemas tirando 6 e colocando meia dúzia… :thumbup:
Por que nao tratar estes erros na camanda de modelo de maneira adequada?]['s
Talvez por que eu nao saiba! 8)
Mas é isso que estou tentando fazer aqui… aprender… Como seria a maneira adequada?
Sem um exemplo completo fica difícil, Felipe.
Realment eos livros vão te ensinar a modelar os aspectos do seu problema como objetos, você vai ter usuários, cartões de crédito, vendas, estoques, grupos… tudo como objetos de negócio.
A camada de apresentação vai receber estímulos dos usuários e vai passar estes para a APIda camada de negócios, que vai fazer as operações nos objetos de acordo com o estímulo. Se for necessário, essa alteraçãod eve disparar uma interação com a camada de persistência, para que atualize o SGBD/XML/PQP de acordo com o estado atual dos objetos.
Desculpe duplicar o tópico mas estou realmente interessado nisso:
Acho que eu to lesado hoje, não to notando a duplicação. A classe Usuario criptografa a senha, e a classe CaixaEletronico autentica(verificando se ela é válida ou não).
Sem um exemplo completo fica difícil, Felipe.Realment eos livros vão te ensinar a modelar os aspectos do seu problema como objetos, você vai ter usuários, cartões de crédito, vendas, estoques, grupos… tudo como objetos de negócio.
A camada de apresentação vai receber estímulos dos usuários e vai passar estes para a APIda camada de negócios, que vai fazer as operações nos objetos de acordo com o estímulo. Se for necessário, essa alteraçãod eve disparar uma interação com a camada de persistência, para que atualize o SGBD/XML/PQP de acordo com o estado atual dos objetos.
É mais ou menos nesse modo que trabalho hj (mais pra menos)…
Acho que depois disso tudo fica uma pergunta ainda:
Como tratar as respostas vindas da camada de persistência? Como fazer para que elas “voltem” para a camada de apresentação, sendo que o Fabio já falou que meus if’s estão loooonge do ideal??? Gerando exceções???
[size=7]eu juro que já to acabano com a perguntação[/size]
Ok, acho que foi ume xemplo mal formulado, ams vamsot entar prosseguir.
Primeiro, acho que estamo enxergando diferente: imagine usuário como um cadastro de usuário, estamos imaginando igual?
Vamos lá, eu quero usar o caixa eletrônico, eu me cadastro no banco XYZ.
A rotina de cadstro vai e criptografa minha senha.
Eu vou usar o caixa eletrônico, o caixa quer saber se a minha senha confere, ele dá um get na senha do usuário (recebendo a versão criptografada) e criptografa a senha que eu informei apra poder comparar.
Você tem duas classes fazendo a mesma coisa (não necessariamente código repetido, mas funcionaldiade repetida. Elas podem usar uma classe utilitária para criptografar, mas aidna assim estão fazendo a mesma coisa em dois lugares diferentes).
Respostas “certas”?
Transofrme os registros em objetos novamente e os jogue na camada de negócios.
Respostas erradas?
Isso é quebra de cotnrato, em Java é tratado com exceções.
É, acho que estamos enxergando diferentemente:
Eu imaginei o Usuario criptografar a senha, e o Caixa Eletronico apenas autenticar, verificar se ela é realmente válida. Porém o Caixa Eletronico receberia uma senha, independente de ela estar criptografada ou não(tudo que ele sabe é que é uma senha, não sabe se esta criptografada, embaralhada, etc).
Agora voltando ao ponto inicial, conclui-se então que neste caso getters e setters não têm sentido nenhum.
Na maiorira das vezes não.
Os beans t~em sentido dentro do cotnexto deles, que não é o suado hoje.
Como tratar as respostas vindas da camada de persistência? Como fazer para que elas “voltem” para a camada de apresentação, sendo que o Fabio já falou que meus if’s estão loooonge do ideal??? Gerando exceções???
Respostas “certas”?
Transofrme os registros em objetos novamente e os jogue na camada de negócios.
Respostas erradas?
Isso é quebra de cotnrato, em Java é tratado com exceções.
Ótimo! Obrigado mesmo…
Acho que por hj tá bom, vou dar uma lida em padrões, agora já tenho uma idéia de “o que fazer com padrões”.
Obs.: Bom, eu cheguei nessa necessidade pq estava vendo que aquilo que o Fernando Anselmo ensinou nao era a melhor opção. Será se todo mundo que trabalha com java sem conhecer os Design Patterns (seja web, local, celular…) grava as informações no banco na mesma classe que exibe os dados??? Tudo a lá Pascal?? É isso que estou percebendo que vc fala que uma grande parte do pessoal trabalha em java como se fosse proceduralmente???
Obs2.: Depois eu volto com mais duvidas… e mais conteúdo tb. Falous…
Respostas erradas?
Isso é quebra de cotnrato, em Java é tratado com exceções.
Completando. Por exemplo deu um erro na camada de persistencia, la no DAO. Imagine que voce tentou inserir um usuario repedido e o teu banco de dados deu erro de PK.
Quem deve saber que deu erro? A tua camada de negocio certo?
Então propage a excecao até ela e trate de maneira conveniente, colocando mensagens de erro que “traduzam” o que ocorreu. Fazendo isso é so enviar esse retorno (com erro ) à tua camada de apresentacao fazendo ela mostrar a mensagem de erro.
Agora como fazer isso?? Tem N artigos, tutoriais na web sobre isso, com framework sem framework, em app web ou mesmo desktop. Sabendo o conceito e o que deve ocorrer vai ser bem mais tranquilo pra ti entender os artigos tutoriais.
Uma dica, baixe projetos open souce e de uma olhada no codigo para aprender. O GUJ2 ou o ONLite (que estamos fazendo pro JavaFree) é uma pedida para ver como frameworks sao aplicados. O JForum é uma boa pedida pra ver como fazer sem framewok algum. eu mesmo ja mexi demais nos codigos do Rafael para estudo, e ver como outras pessoas implementam as coisas. 
]['s
O nome da classe realmente foi mal colocado:
mude para :
class Autenticacao
{
}
Essa classe não define uma entidade mas uma operação ou um conjunto de operações.
E login nesse sentido que eu coloquei é um substantivo e não um verbo,
pode dar perfeitamente um nome para uma classe.
Não se pode comparar isso com VB. Não é OO puro, mas também não é algo horrivel…
Felipe, Design Patterns são consequências de uma modelagem OO. Se você estudar OO, ao ler um livro sobre padrões, as coisas vão fazer muito mais sentido do que simplesmente tentar aplicar aquelas soluções no seu projeto. Se seus objetos não foram bem pensados e não são inteligentes o bastante, não há Design Pattern que vai salvar o seu projeto hehe
E falo isso pois estou passando exatamente por esse momento, e sofrendo com o código já escrito usando “mvc” 
Tem umt exto ótimo do Meyer sobre “achar substantivos que são classes”, no primeiro liro da lista do outro tópico (eu li ontem
) dê uma olahda se possível. basicamente, isso não é a melhor nem a úncia maneira de se descobrir uma classe em um sistema.
Chegamos á uma subjetividade muito grande neste exemplo. Se autenticação é uma classe ou não depende do contexto do sistema.
jprogrammer, como falei: se você quer questionar a utilidade ou a super-estimaçãod e OO, não é o tópico certo, simplesmente porque eu estou tentando te msotrar uma maneira que eu considero legald e fazer OO, mas se você não acredita em OO, não tem o que te msotrar (pelo menos não por enquanto
)
Será se todo mundo que trabalha com java sem conhecer os Design Patterns (seja web, local, celular…) grava as informações no banco na mesma classe que exibe os dados??? Tudo a lá Pascal?? É isso que estou percebendo que vc fala que uma grande parte do pessoal trabalha em java como se fosse proceduralmente???
viu pq eu falei do livro?
Sim vejo que você é um entusiasta do OO.
E vejo que você tem profundo conhecimento também.
Eu gosto muito do OO, ele torna a programação muito mais inteligente e auto-documentavel.
Não estou sendo contra, apenas quero resaltar que as vezes temos que dar uma quebradinha nos paradigmas.
Podemos sim fazer isso sem perder a elegancia.
jprogrammer
Você está confundindo layers com tiers.
Um layer é uma separação lógica de partes do teu programa, um layer só deve falar com os layers ajdacentes a ele.
Um tier é uma camada física do seu sistema.
Ou seja, enquanto a separação entre layers é tenue e normalmente depende dos desenvolvedores definirem as fronteiras, já com tiers basta procupar por um cabo de rede interconectando eles.
Layers e tiers servem propósitos diferentes, BEM diferentes. Layers existem para melhorar o organização do software e facilitar o desenvolvimento. Tiers existem para segmentar dados e processos, quase sempre para atingir maior performance.
Existem boas formas para se escreve o software que faz a comunicação inter-tier e inter-layer.
Comunicação inter-tier costuma ser feita usando DTOs, que é uma representação compacta e sem comportamento dos teus objetos. Eles servem apenas para esse propósito.
Objetos do mesmo tier devem existir no mesmo layer pois eles costumam promover uma rica troca de mensagens entre sí, oque inviabilizaria seu uso entre tiers.
Por último vou falar sobre essa tua paranoia infundada sobre sistemas distribuidos.
É extremamente raro encontrar um sistema distribuido que seja uma federação de nós, o modelo dominante é master/workers com alocação dinâmica de trabalho.
No universo J2EE você vai encontrar quase nenhum caso de SD federado, é mais provavel com JINI - e eu nunca ouvi falar de JINI no mundo real.
Um exemplo de SD federado que você vai encontrar provavelmente é caching distribuido coerente, e isso 99,9998% das pessoas usa algo pronto e não escreve o seu.
Dentro do modelo master/workers essa tua preocupação de muitos objetos remotos é exagerada, quando existe é por incompetencia dos arquitetos que não souberam planejar.
Felipe, Design Patterns são consequências de uma modelagem OO. Se você estudar OO, ao ler um livro sobre padrões, as coisas vão fazer muito mais sentido do que simplesmente tentar aplicar aquelas soluções no seu projeto. Se seus objetos não foram bem pensados e não são inteligentes o bastante, não há Design Pattern que vai salvar o seu projeto heheE falo isso pois estou passando exatamente por esse momento, e sofrendo com o código já escrito usando “mvc” :|
Aí, Lipe, OO basicamente eu sei, tb nao sou assim tão cru… na verdade eu achava que sabia mais um pouquinho :mrgreen:
O projeto que estou foi assim, digamos, bem estruturado. Não foi melhor pq eu nao sabia dos padroes e tals… mas agora já está simples de entender os design patterns.
Obrigado!
Pergunta fatal e inevitável: Qual um bom livro sobre o assunto? Core patterns?
louds gostei da sua explicação e de sua visão.
Isso ampliou mais minha visão.
Você teria a “conexão” das tiers sem compromentimento das layers.
Um recurso poderia ser o DTO.
Mas isso não poderia gerar redundancias ?
O client iria conversar com o DTO. O DTO passa os dados para o serviço.
O serviço passa para as classes de domínio que fazem as operações.
então a gente teria:
class UsuarioDTO
{
private String nome;
private Strnig senha;
//getters and setters
}
// pode ser qualquer servico EJB, RMI…
class ServicoAutenticacao
{
public void autenticar(UsuarioDTO usuarioDTO)
{
Usuario usuario = new Usuario();
usuario.setNome(usuarioDTO.getNome())
usuario.setSenha(usuarioDTO.getSenha())
usuario.autenticar();
}
}
class Usuario
{
private String nome;
private Strnig senha;
//getters and setters
public void autenticar()
{
//
}
}
E qual seria uma solução??
E qual seria uma solução??
Delegue essa responsabilidade a uma classe.
~
class Usuario{
private Senha senha;
public boolean verificarSenha(Senha s){
return criptografar(s).equals(senha)
}
public void defineSenha(Senha s){
senha = criptografar(s).equals(s)
}
public Senha criptografar(Senha s){
...
}
}
Shoes, mas se a classe usuário for remota, o cliente teria que criptografar a senha antes de enviar pela rede. E então?
Tu tá andando muito com o jprogrammer
Leia o psot do louds.
Isso é coisa de infra-estrutura 
Renato,
Nesse caso usa-se SSL pra criptografar os dados, tu nao vai deixar teu algoritmo de criptografia no cliente neh?
Imagina feito em javascript no cliente. :shock:
]['s
Entrando em criptografia que eu saiba a melhor forma de criptografar senha é usando algoritmo de hash. E que eu saiba sistemas criptográficos cujo segredo está baseado no algoritmo não são nada seguros. Hashs MD5, SHA-1, e criptografias assimétricas como RSA não são assim.
A questão é que a criptografia é um aspecto secundário, e agora estou (en)tendendo pro que o Shoes está falando. O cliente tem que criptografar a senha por causa da rede, não do banco, por isso sua idéia de usar SSL é válida, ou até mesmo um algoritmo proprietário. Ele nem de longe precisará saber como a senha é armazenada no banco, nem mesmo se ela é criptografada ou não!
PS: eu disse alguma coisa sã?
Tá meio embolado, mas a questão é por aí sim…acho
No exemplo>
A criptografia do exemplo é para armazenamento
A criptografia “na rede” seria SSL ou coisa que o valha
DTOs são classes que fazer papel do wire-format quando estamos falando de objetos distribuidos (RMI, Corba, etc).
Ou seja:
class AuthenticationBusinessDelegate {
public Principal auth(String user, String pass) {
AuthDTO dto = new AuthDTO();
dto.setUser(user);
dto.setPass(pass);
Authentication auth = //objeto EJB/CORBA/RMI/WS
AuthResultDTO res = auth.doLogin(dto);
return res.getPrincipal();
}
}
DTOs não são objetos de primeira classe, mas sim amontoados de dados, por isso que eles só prestam para transmitir os dados entre os tiers.
Isso é o arroz-com-feijão-e-gororoba de tunning de EJB :lol:
Pena que não deu para participar mais ativamente deste tópico… 
Mas Philip… quero tirar algumas dúvidas quanto ao que você escreveu ai em cima.
Eu sempre imaginei que devessemos primeiramente nos preocupar com a camada de negócio, e depois a camada de apresentação + persistência. Até aqui sem problemas…
O problema mesma começa na dificuldade de ver alguma coisa funcionando. Deixe-me tentar explicar com um exemplo!!!
Numa modelagem qualquer eu criei uma classe chamada aluno. Implementado de acordo com a modelagem, ficaria mais ou menos assim:
public class Aluno {
private String nome;
private String idade;
// outros atributos
// getters and setters
public void calculaMedia() {
// corpo do metodo
}
public void salvar() {
// corpo do metodo
}
public void incluir() {
// corpo do metodo
}
public void excluir() {
// corpo do metodo
}
// outros metodos
}
Nesta caso acima é tranquilo para criar um teste e testar o metodo calculaMedia. Mas se na minha modelagem tenho os metodos incluir, excluir e etc… como faço para testá-los sem ter a persistência???
Outra dúvida seria o fato de que os métodos incluir, excluir, alterar e salvar deveriam estar em um DAO! Ou seja, eu devo colocar esses métodos na minha classe de negócio durante a modelagem???
Outra dúvidazinha!!! Se eu começar o desenvolvimento do meu sistema focando a classe de negócio, eu teria que aplicar nas minhas classes de negócio o famoso teste unitário! Até aqui tranquilo. Mas eu preciso testar DAO e Actions???
Quando você faz a modelagem você também já pensa nos DAO’s???
Abraços!!!
Thiago Senna
Creio que neste caso, você poderia fazer uma chamada ao DAO, dentro do seus métodos slvar, exluir, etc…
Oi,
Testes unitários + mock objects são uma ótima alternativa 
Não entendi o que vc quis dizer…
Você deve testar o que você acha que deve ser testado (tipo: nãot este getters e setters burros - aliás: não use getters e setters burros), mas tem outros tópicos sobre isso aqui 
Modelagem? Tipo ensinado na facudlade, milhões de diagramas?
Dica: pare de pensar na “modelagem” e pense no domínio. Você pdoe já ir pensando nos DAOs, só que é legal você se concentrar pirmeiro em resolver seu problema, através dos objetos de negócio. Infelizmente quando o sistema é grande demais, isso fica cada vez mais difícil, mas em 99% dos sistemas isso tem tudo para funcionar muito bem 
[]s
Abraços!!!
Thiago Senna[/quote]
Bom, tentarei explicar melhor!
Suponha que eu tenho uma classe chamada SalaDeAula e outra chamada Aluno.
Uma sala pode conter vários alunos, correto???
Na minha classe sala eu tenho um método que retorna uma lista contendo todos os alunos desta sala. Até aqui tranquilo. JUnit resolveria meu problema.
Mas este mesmo problema poderia ser resolvido com um DAO, no qual eu passaria uma simples query com uma cláusula where. Ai eu jogaria os resultados numa collection e mandaria esta collection para minha interface gráfica.
Agora vou tentar expor realmente minha dúvida.
Quando meu action for chamado para realizar a operação de listar todos os alunos de determinada sala de aula o correto seria:
1 - Criar uma objeto Sala.
chamar o método do dao que retorna uma coleção de alunos.
colocar este coleção de aluno mo método setAlunos do objeto sala.
retornar para a interface gráfica o resultado do método sala.getAlunos()
2 -
chamar o método do dao que retorna uma coleção de alunos.
retornar para a interface gráfica o resultado.
Acabei mudando um pouco a minha dúvida… mas essa é uma dúvida que tá me encomodando pacas!!
Abraços!
Vou tentar explicar, mas eu sou tosco. O que voce quer mesmo eh ler mais sobre Domain-Driven Design, Test-Driven Design e Dependency Injection. Coisas que o google e a temporeal/amazon te ajudam bem mais que eu.
Supondo que voce tem uma Sala com varios Alunos:
Quer adicionar um novo Aluno a uma Sala? Que tal:
Aluno aluno = new Aluno.create("Rocky Balboa", sala);
aluno.save(); // insert into alunos values ('Rocky Balboa', 12);
Enfim, coisas que o Hibernate ja faz, mas com uma interface que faz sentido pro seu sistema, pras suas regras de negocio.
Então neste caso não haveriam DAO´s?O própio ‘bean’(sim, sei que este termo é infeliz mas não achei melhor) seria responsável por sua persistência?Ele mesmo faria o papel do DAO?
Eu sempre penso em ‘beans’ como entidades básicas, por exemplo Aluno seria uma entidade do sistema, porque aí toda regra de negócio eu faço utilizando um objeto Aluno.
E tenho uma classe AlunoDAO que nela eu implemento os métodos de persistência.
Olá cv, tudo jóia???
Vou tentar explicar, mas eu sou tosco. O que voce quer mesmo eh ler mais sobre Domain-Driven Design, Test-Driven Design e Dependency Injection. Coisas que o google e a temporeal/amazon te ajudam bem mais que eu.
Quero direito de defesa pela alfinetada… rsrsrs… 
O google ajudaria, desde que eu soubesse que existe esse negócio de domain-driven design e que eles pudessem resolver meu problema.
Sendo assim, o problema pelo jeito é eu mesmo que não estou por dentro destes negócios todos!!! Agora com o toque que você deu, agora vou saber tirar maior proveito do Google…
No entanto, no exemplo que você citou vc usou o método aluno.create(…)
É aqui que dá um nó na minha cabeça. Essa forma que você mostrou é sem dúvida a mais elegante. Mas considerando que estou em um projeto onde o pessoal tem as classes de negócio e o DAO (dao de sql puro… nada de hibernate, IoC… blábláblá), então como fica?
1 - o método create do objeto aluno deve instanciar o DAO ?
ou
2 - o Action instância o aluno e passa ele para um DAO?
…
Desculpem-me pela ignorância… Eu acho que me polui lendo alguns livros de patterns, e acabei me convencendo de que objetos não devem ter métodos como create, save e sim que eles devem ficar no DAO. Na faculdade aprendi o contrário. Vocês dizem o contrário também Poxa? E agora??? Eu misturo tudo, ou separo!!!
Abraços!
Objetos devem ser salvos para persistirem? Não, eles devems er criados e destruídos, enquanto eles estiverem no intervalo entrte um e outro eles existem/são persistidos.
Ah, cacete, tem aquele problema: ninguém tem memória para guardar tantos objetos (o time do prevayler que o diga…), então a gente tem que guardar isso em algum lugar. Um SGBD seria ótimo para guardar estados e fazer algumas macumbas de DBA.
Ok, mas isso é uma limitação. A menos que fortemente apoiada pela linguagem (e não é o caso de java), você vai ter que colocar seus objetos de alguma forma no sgbd (ou seja lá o que você use).
Ok, então existem basicamente duas estratégias:
- O objeto se persiste
- Alguém persiste o objeto
Com o que falei de metadata+AOP (ou outra cosia parecida mas com menos voodoo)a primeira se tornaria (talvez) viável, mas puramente um objetos e persistir no banco é algo complicado.
Atualment eeu uso a estretégia de quem coordena a ação persiste. O cara vai ter que criar um objeto novo? Então após criar ele manda o objeto pro dao. Eu sicneramente acho isso um lixo, mas para aplicações “do mundo real” gerentes, project managers, rpazos e custos enchedores de saco) acho que funciona.
Eu tou usando active records, shoes, e funciona legal tambem. Em Java eh mais pentelho de implementar (mas eu cheguei a dar um exemplo pro Lipe naquela thread sobre encapsulamento… alguem linka pra mim?) de como a coisa funciona mais ou menos.
A diferenca eh que em Ruby nao tem nada da enchecao de saco :mrgreen:
public class Aluno {
private String nome;
private String idade;
// outros atributos
// getters and setters
public void calculaMedia() {
//faz um monte de coisa
// e depois tchanan
}
public void salvar(Aluno aluno) {
//faz um monte de coisa
// e depois tchanan
Dao dao = DaoFactory.getAlunoDAO();
dao.salvar(aluno);
}
public void listar(Aluno aluno) {
//faz um monte de coisa
// e depois tchanan
Dao dao = DaoFactory.getAlunoDAO();
dao.listar(aluno);
}
public void excluir(Aluno aluno) {
//faz um monte de coisa
// e depois tchanan
Dao dao = DaoFactory.getAlunoDAO();
dao.exluir(aluno);
}
// outros metodos
}
Essa seria uma abordagem correta , OO?
public class Aluno { public void salvar(Aluno aluno) { //faz um monte de coisa // e depois tchanan Dao dao = DaoFactory.getAlunoDAO(); dao.salvar(aluno); } }
Perae, o aluno salva outro aluno (ok, eles poderiam estar colando numa prova :D )? *Se* for fazer isso, ele deveria salvar a si mesmo ;)
Forma correta é subjetivo, abstrato, blablabla, mas considerando que estamos fazendo gambiarras de qualquer jeito, a maneira com menos código de persistência possível (dentro das outras best-practices, claro) é excelente. Seja ele qual for ;)
Eu tou usando active records, shoes, e funciona legal tambem. Em Java eh mais pentelho de implementar (mas eu cheguei a dar um exemplo pro Lipe naquela thread sobre encapsulamento… alguem linka pra mim?) de como a coisa funciona mais ou menos.
A diferenca eh que em Ruby nao tem nada da enchecao de saco
CV, ta linkado http://www.guj.com.br/posts/list/15/20668.java

Como o cv já falou, não faz sentido um Aluno ser responsável por ações que envolvem muitos Alunos. Portanto estes métodos poderiam ser estáticos 
E vocês estão esquentando demais a cabeça com o lance de onde por o método que acessa o banco. Vocês leram o que o Shoes falou sobre o problema da persistência?
De qualquer maneira, no P of EAA, há a pattern indicada pelo cv, Active Record, que diz o seguinte:
An object that wraps a row in a database table or view, encapsulates the database access, and adds domain
logic on that data.
…
An object carries both data and behavior. Much of this data is persistent and needs to be stored in a database.
Active Record uses the most obvious approach, putting data access logic in the domain object. This way all
people know how to read and write their data to and from the database.
…
Because of the close coupling between the Active Record and the database, I more often see static find
methods in this pattern. However, there’s no reason that you can’t separate out the find methods into a separate
class, as I discussed with Row Data Gateway (152), and that is better for testing.
…When to Use It
Active Record is a good choice for domain logic that isn’t too complex, such as creates, reads, updates, and
deletes. Derivations and validations based on a single record work well in this structure.
…
Another argument against Active Record is the fact that it couples the object design to the database design.
This makes it more difficult to refactor either design as a project goes forward.
Acho que vocês, assim como eu há pouco tempo, estão querendo fazer bonito, mas esqueceram que o objetivo da coisa toda é fazer algo fácil de ler, manter, reusar e estender.
public class Aluno {
private String nome;
private String idade;
private MaterialEscolar material
// outros atributos
// getters and setters
public void calculaMedia() {
//faz um monte de coisa
// e depois tchanan
}
public void salvar(MaterialEscolar material) {
//faz um monte de coisa
// e depois tchanan
Dao dao = DaoFactory.getAlunoDAO();
dao.salvar(material);
}
public void listar(MaterialEscolar material) {
//faz um monte de coisa
// e depois tchanan
Dao dao = DaoFactory.getAlunoDAO();
dao.listar(material);
}
public void excluir(MaterialEscolar material) {
//faz um monte de coisa
// e depois tchanan
Dao dao = DaoFactory.getAlunoDAO();
dao.exluir(material);
}
// outros metodos
}
Isso seria hmmmm....... digamos ...... "correto" e OO ?
Ok, então existem basicamente duas estratégias:
- O objeto se persiste
- Alguém persiste o objeto
Sobre isso que estava pensando. Colocar código de persistência no próprio objeto, de modo que podem ser usados sem se preocupar com isso seria bom no sentido de que os usuários dos objetos não precisam se preocupar em salvar os objetos, além de tornar o código “mais OO” (mais natural?), pelo o que estou entendendo.
Mas tem aquela coisa de que no entanto nem os próprios objetos em si deveriam preocupar-se com persistência, ela deveria ser automática, visto que é uma necessidade “estrutural” e não lógica de negócio. Além disso sua lógica fica presa ao tipo de persistência usado e mesmo com abstrações ela ainda vai depender das interfaces DAO. Ou seja, código “secundário” embutido na lógica. Portanto acho que a segunda estratégia, de o usuário persistir o objeto é melhor.
Além disso sobre “colocar dados e operações sobre estes dados na mesma classe”, acho legal (pelo menos até este segundo!) manter separados os dados e a lógica. Principalmente em casos que a “lógica” da aplicação não passa de consultas, adicões e remoções de entidades no banco de dados. Ou seja, lógica que acessa a camada de persistência. Isso cria um “desacoplamento” que acho legal, porque posso fazer várias lógicas sobre os mesmos dados. Assim, minhas classes de dados (“beans burros”) não passariam de VOs/DTOs que representam as entidades do banco de dados.
Atualment eeu uso a estretégia de quem coordena a ação persiste. O cara vai ter que criar um objeto novo? Então após criar ele manda o objeto pro dao. Eu sicneramente acho isso um lixo, mas para aplicações “do mundo real” gerentes, project managers, rpazos e custos enchedores de saco) acho que funciona.
Por que você acha isso um lixo? Eu não acho, como demonstrei acima.
Assim, minhas classes de dados (“beans burros”) não passariam de VOs/DTOs que representam as entidades do banco de dados.
Pois é, Renato, ams acho que esse tipo de aplicação “burra” (pega-do-banco-mostra-na-tela-volta-pro-banco) ficaria melhor feito em outra linguagem (talvez Delphi, cacete, esse topico fala do assunto do outro e o outro do assunto desse…),
Por que você acha isso um lixo? Eu não acho, como demonstrei acima.
Porque simplesmente não é natural. É como DTO (Ok, não é tão horrível quanto DTO): eu uso poruqe aidna não consegui pensar e não me ensinaram nada melhor.
Fazer persistência coordenada por caso de uso é algo…sei lá…sintético demais.
Renato, discordo quando diz que “Além disso sua lógica fica preso ao tipo de persistência”, basta usar interfaces. Mas concordo com os outros pontos.
Colocar parte da lógica de persistência no objeto e outra parte em outro lugar para mim não faz sentido. Ou pretendem colocar aqueles maravilhos métodos de busca com 75 argumentos no Aluno?
E outro problema: o método “save” é chamado no server, certo? Mas o objeto também existe no cliente em aplicações não-web. Como proceder então? throw new ChamouOMetodoNoLugarErradoSeuBurro? Prefiro não.
Consertando o exemplo, entao, e usando o exemplo da classe Base que eu dei no outro topico (valeu pelo link, Luiz):
public class Sala extends Base<Candidato> {
private String nome;
private Set<Aluno> alunos;
public void setNome(String nome) { ... }
public String getNome() { ... }
public void addAluno(Aluno aluno) { ... }
public void removeAluno(Aluno aluno) { ... }
public Set<Alunos> getAlunos() { ... }
}
public class Aluno extends Base<Candidato> {
private String nome;
public void setNome(String nome) { ... }
public String getNome() { ... }
}
Levando em conta que os metodos save, load, find e tudo mais estao na classe Base, e pra piorar um pouco alguns deles sao estaticos (pq nao faz sentido usar uma instancia de Aluno pra procurar outros), o codigo ate que fica simplezinho.
Um problema, no entanto, eh quando voce quer testar esse treco sem ter que ir pro banco de dados de verdade. Como nao da pra sobrescrever Base.save() so de alegria, o que vc pode fazer eh algo mais ou menos assim:
public class Base<T extends Base> {
private static Session session;
public static void setSession(Session session) { ... }
...
}
Onde Session eh uma Session do Hibernate, mesmo. Num teste unitario, tudo que voce precisa fazer eh chamar setSession e passar um mock, e garantir que o comportamento ta certinho.
Falei merda? :)
E outro problema: o método “save” é chamado no server, certo?
[momento viagem ao mundo utopico]
o problema: a menos que seja algo funcional, essa droga de método não deveria existir!
[/momento viagem ao mundo utopico]
Se infelizmente ele existe, se precisamos controlar a persistência na mão mesmo, a pergunta:
- Coordenar a persistência por caso de uso (por funcionalidade, na verdade) é legal?
Eu acho que é o jeito mais “limpinho” sem macumba, mas me encomoda. Você acaba endo muitos pseudo-façades coordenando os dados no seu sistema…
Voltando ao tema central…
O Gavin King deu uma palestra anteontem (Sábado) no RioJavaSummit e colocu uma coisa bem interessante:
“Com o EJB 3.0, EJBs são os novos JavaBeans”, eu encaro isso no sentido que eles representam um modelo que foi introduzido pelos beans clássicos, mas de uma outra maneira. Beans clássicos possuem “injeção de dependência manual”, os ejbs já utilizam IoC…
Independente da minha opinião sobre a spec do EJB 3.0, achei um ponto bem interessante.
É isso que não me entra na cabeça, um objeto ser responsável por persistir ele mesmo, ou ser responsável por ações com diversos objetos do mesmo tipo.
Desta forma não estaríamos ferindo a regra de responsabilidades?
E particularmente eu acho que separar por responsabilidades fica mais fácil de se manter.
Rafael, pra evitar que cada um va pra um lado na conversa, e pra evitar confusao: qual eh a sua definicao de “regra de responsabilidade” que fazer isso estaria ferindo?
public class Aluno{
public void save(Aluno aluno){...}
public void delete(Aluno aluno){...}
}
Não consigo entender/aceitar um aluno salvar ou deletar ele mesmo, pois cada objeto/camada/ou sei lá o quê deveria ser reponsável por algo em específico. Por exemplo eu teria um Aluno responsável por validar e modificar as informações que um aluno tem, e um outro objeto (provavelmente um DAO), responsável por persistir o Aluno.
Ao menos foi assim que aprendi e venho fazendo.
Obs:Acabei de notar que DAO passou a ser uma obrigação pra mim, não um padrão sugerido.
Pois é, Renato, ams acho que esse tipo de aplicação “burra” (pega-do-banco-mostra-na-tela-volta-pro-banco) ficaria melhor feito em outra linguagem (talvez Delphi, cacete, esse topico fala do assunto do outro e o outro do assunto desse…),
UUuááááá que preconceito. Não posso programar em Java coisas simples?? Pode ser simples mas se eu quiser multiplataforma uáááááááááááá
Porque simplesmente não é natural. É como DTO (Ok, não é tão horrível quanto DTO): eu uso poruqe aidna não consegui pensar e não me ensinaram nada melhor.
Bom, é por que toda vez que você for usar a lógica vai ter que se preocupar em salvar os objetos, e isso não é natural. É isso?
Fazer persistência coordenada por caso de uso é algo…sei lá…sintético demais.
[color=red]Compile Error[/color]
Eu não sei nada de UML 
Bom na aplicação que fiz com um colega temos o seguinte cenário:
Um módulo web de uma aplicação de help desk. Basicamente são duas coisas que o sistema faz: cadastra uma nova solicitação de atendimento, e consulta o status de um atendimento efetuado.
A lógica é simples acesso a banco, exceto o lance de converter datas. Nós criamos então as classes organizadas assim:
- pacote “logica”: A lógica da aplicação, são as classes DataAccess que é um DAO e DateConverter para converter datas;
- pacote “dados”: Service, ServiceRequest, HistoryItem. São as “entidades” da aplicação, são beans burros.
Assim se eu quero abrir uma solicitação eu crio um ServiceRequest e peço pro DAO gravá-lo. Se eu quero consultar o andamento de um atendimento, eu peço pro DAO me devolver um Service para consultar.
Assim é a camada controladora (num MVC) é que instancia o DAO, que na verdade contém toda a lógica (pouca), cria os beans e pede para salvá-os. Se houvesse mais lógica não relacionada a persistência, eu vou criando classes separadas (quanto menos melhor) como por exemplo DateConverter, e as usando sobre minhas entidades. Ou poderia embutir tal lógica nos beans, tornando-os mais inteligentes e mais “OO”. Mas não fiz isso (p.e. não coloquei a conversão de datas embutida e sim na parte “logica”) porque achei que tinha que ser assim, por causa do DTO/VO.
É isso aí. Que Zahl me ajude, ou Jesus Cristo.
Qual a sua opinião?
Renato, discordo quando diz que “Além disso sua lógica fica preso ao tipo de persistência”, basta usar interfaces. Mas concordo com os outros pontos.
É aquilo que eu disse, mesmo com interfaces você deixa “marcas” de persistência dentro da lógica. Sua lógica fica dependente das interfaces e não podem ser reutilizadas fora de um contexto “persistencial”. É o que eu acho.
Esse se a gente tivesse uma classe que identificasse o registro e outra a coleção de registros não ficaria mais decente.
ex:
class Funcionario
{
private int codigo;
private String nome;
// setters e getters
}
class Funcionarios
{
private Funcionarios() {}
public static void adicionar(Funcionario func)
{
}
public static void remover(int codigo)
{
}
}
Funcionario funcionario = new Funcionario()
funcionario.setCodigo(1);
funcionario.setNome(“Maria”);
Funcionarios.adicionar(funcionario);
Sei lá, isso não seria mais intuitivo.
Uma coleção de funcionarios que adiciona para sua lista um funcionario.
Ela não é instanciável, pois não representa uma instancia, mais sim um colecão de instancias.
Renato, falei aquilo pois você disse “Além disso sua lógica fica preso ao tipo de persistência”. Considerando sua retificação concordo completamente.
jprogrammer, desta maneira você só renomeou a classe FuncionarioDAO para Funcionarios hehe
Então o DAO não é tão grotesco assim.
Não interessa a implementação, o que importa é a interface.
Para o restante do sistema, você estará adicionando, retirando, recuperando itens de uma lista, e não persistindo em um banco.
Não sei o que tem de errado um método com um nome “salvar”, “adicionar”, que neste caso indentifica uma operação do sistema.
Poderia ser faturar, descontar, processar, matricular, internamente ele poderia fazer qualquer coisa.
Se o caso de uso for inserir funcionário , não tem problema algum.
jprogrammer, após a postagem do Shoes ficou bem claro que DAO não é grotesco, é apenas um aspecto do sistema.
você estará adicionando, retirando, recuperando itens de uma lista, e não persistindo em um banco.
hum, esse é o objetivo de DAOs, persistir o objeto, não importa onde. Se é numa Collection em memória ou enviando mensagens para um cara com uma máquina de escrever digitando todos os dados.
interface DAO{
public void salvar( Object obj );
}
class BancoDAO implements DAO {
public void salvar( Object obj ) {
connection.save( obj );
}
}
class CaraDaMaquinaDeEscreverDAO implements DAO {
public void salvar( Object obj ) {
messenger.send( obj );
}
}
Ainda mais implementado com Generics, como o cv sugeriu.
Sim, o objetivo do DAO é persisitir no banco ou em qualquer outro lugar.
Mas para o restante do sistema, ele não faz isso, é apenas uma implementação interna do DAO.
Isto só é verdade utilizando AbstractFactories ou IoC 
Eu tou usando active records, shoes, e funciona legal tambem. Em Java eh mais pentelho de implementar (mas eu cheguei a dar um exemplo pro Lipe naquela thread sobre encapsulamento… alguem linka pra mim?) de como a coisa funciona mais ou menos.A diferenca eh que em Ruby nao tem nada da enchecao de saco :mrgreen:
Eu tava pensando sobre como o pattern de unit of work poderia ajudar nesse caso.
O padrão prega que uma entidade externa controle a persistencia do modelo. Com um pouco de AOP isso ficaria quase transparente.
Então em vez de fazer:
Aluno aluno = new Aluno.create("Rocky Balboa", sala);
aluno.save(); // insert into alunos values ('Rocky Balboa', 12);
Ficaria:
Aluno aluno = new Aluno("Rocky Balboa", sala);
Isso, claro, funciona para exemplos e programas de demonstraçãoo, seria necessario uma API intrusiva para apagar entidades, marcar como transientes e fazer detachment para funcionar no mundo real. Ou alguma coisa que não saquei.
Poderiamos ser ainda mais malignos com AOP e fazer o seguinte:
Aluno aluno = new Aluno(1234); //<-- primary key dele
Na verdade com AOP poderiamos detectar o movimento labial do usuário e gravar um novo Aluno quando ele fizesse o som de bolinhas de sabão estourando :XD:
Lipe, que não gosta do que teme.
pop :mrgreen:
Sei nao, usar AOP demais me estragou e ate hoje eu ainda frequento grupos de apoio. Usar uma linguagem mais dinamica tem funcionado bem, grassadeus :mrgreen:
Isso, claro, funciona para exemplos e programas de demonstraçãoo, seria necessario uma API intrusiva para apagar entidades, marcar como transientes e fazer detachment para funcionar no mundo real. Ou alguma coisa que não saquei.
No caso de marcar como transientes, não é possivel usar a mesma abordagem do Hibernate não? Tipo, se o id está com o valor indicado pelo unsaved-value, então o treco é transiente.
valeuz…