POJO’s são classes JAVA que serão vinculadas com o Banco de Dados?
Qual a maneira correta de se fazer esses POJO’s, eu vi que tem o hbm.xml, mas me disseram que é um método muito antigo para se fazer isso, o correto é fazer uma classe com os mesmos atributos que estão no banco e implementar serializable e mapear a classe com o banco através das anotações. É isso?
Obrigado
Cara, de maneira bem básica, é isso mesmo o que você falou, os atributos estão vinculados às colunas do banco de dados.
A questão de usar hbm.xml ou annotations está vinculada ao Hibernate. Ele evoluiu e permite que usemos annotations ao invés de xml (foi gerado um movimento chamado XML Hell, pois era de difícil manutenção).
Quanto ao POJO, como o link do nosso amigo ai em cima diz: Plain Old Java Objects…
Cara, se é OLD, eu não vejo motivos para usá-los. Hoje em dia o Hibernate consegue popular a sua classe sem que você tenha getters e setters, ele usa reflection para fazer isso.
Ou seja, pense bem antes de fazer um monte de getters e setters: qual a diferença real entre getters e setters e atributos públicos?
Hoje em dia o Hibernate permite que você crie métodos baseado na sua necessidade, e não na necessidade dele.
EDIT
Quanto à implementação de Serializable só é necessária quando você tem tabelas com IDs compostos…
Mas se não, só deve implementar quando VOCÊ precisar.
Não seria a importância do encapsulamento, da segurança?
Não seria a importância do encapsulamento, da segurança?[/quote]
Sim, eu vejo que você deve criar seus objetos baseados na modelagem do seu sistema. Independente do framework que vai usar.
E um POJO é basicamente isso, é um objeto Java, que não sabe se será persistido com Hibernate, com JDBC, ou até se será persistido ou não.
Quanto à getters e setters isso sempre gera polêmica. Se seu modelo é anêmico, provavelmente vai ter eles pra todos os atributos da classe, agora se trabalha com um modelo mais rico, por ter um sistema modelado por DDD, aí provavelmente sua API terá mais métodos de negócio do que getters e setters em si.
Não seria a importância do encapsulamento, da segurança?[/quote]
O Rodrigo falou MUITO bem!
Eu sou contra esse modelo mais anêmico que ele cita.
A ideia é encapsular, um monte de getters e setters não está encapsulando nada, não tem regras, não tem validações, não tem negócio e qualquer classe pode fazer o que quiser com essa instancia…
Mais ou menos assim:
public class ContaCorrente {
private double saldo;
private double limite;
// getters e setters
}
Para fazer um depósito nessa conta eu vou precisar lembrar de aumentar o saldo, se eu for fazer uma retirada eu vou precisar lembrar de verificar o limite e fazer a retirada…
Sem falar que se eu esquecer de verificar o limite, eu posso deixar o cara retirar 500 milhões da conta dele e tudo bem…
Para mim, a regra de negócio DEVE ficar nessas classes, quando fizerem sentido.
Rafael Guerreiro,
E se eu estiver usando um framework, como o Spring MVC, que usa esses getters e setters pra exibir os atributos dos objetos nas jsp?
Não seria a importância do encapsulamento, da segurança?[/quote]
O Rodrigo falou MUITO bem!
Eu sou contra esse modelo mais anêmico que ele cita.
A ideia é encapsular, um monte de getters e setters não está encapsulando nada, não tem regras, não tem validações, não tem negócio e qualquer classe pode fazer o que quiser com essa instancia…
Mais ou menos assim:
public class ContaCorrente {
private double saldo;
private double limite;
// getters e setters
}
Para fazer um depósito nessa conta eu vou precisar lembrar de aumentar o saldo, se eu for fazer uma retirada eu vou precisar lembrar de verificar o limite e fazer a retirada…
Sem falar que se eu esquecer de verificar o limite, eu posso deixar o cara retirar 500 milhões da conta dele e tudo bem…
Para mim, a regra de negócio DEVE ficar nessas classes, quando fizerem sentido.[/quote]
Desta maneira, você está dizendo que não precisamos trabalhar com outras classes, não é? Afinal, tudo ficará apenas no ‘POJO’.
A questão dos getters e setters é um pouco mais complexa que simplesmente encapsular. Ela está ligada a outros conceitos, como o $ERVER colocou. E não é preciso nem utilizar um framework de terceiro para isto, basta seguir o padrão java…
Do meu ponto de vista, a regra de negócios deve ficar isolada, permitindo que a manutenção seja mais simples e limpa possível.
Pois é, nesse caso, quando vamos trafegar informações diretamente entre o browser e o server (aonde entram os frameworks MVCs) é ideal que a gente use um tipo de objeto chamado DTO.
Ou seja, Data Transfer Object. É importante que você tenha 1 DTO para cada FUNCIONALIDADE, ou seja, uma mesma entidade pode ter vários DTOs.
Os maiores focos do DTO são:
1- Não afetar as regras de negócio (getters e setters atrapalham as regras);
2- Evitar o Mass Assignment, uma falha de segurança bastante preocupante.
drsmachado,
E quanto a esse isolamento das regras de negócio, você cria uma camada especificamente pra isso? Como ela fica?
Os dois únicos projetos que fiz aqui eram muito pequenos, então nem foi necessário chegar a esse nível de abstração, mas tenho muita curiosidade em aprender.
Caso tenha algum link que possa me clarear um pouco mais sobre o assunto, agradeço.
Abraços.
[quote=drsmachado]
Desta maneira, você está dizendo que não precisamos trabalhar com outras classes, não é? Afinal, tudo ficará apenas no ‘POJO’.
A questão dos getters e setters é um pouco mais complexa que simplesmente encapsular. Ela está ligada a outros conceitos, como o $ERVER colocou. E não é preciso nem utilizar um framework de terceiro para isto, basta seguir o padrão java…
Do meu ponto de vista, a regra de negócios deve ficar isolada, permitindo que a manutenção seja mais simples e limpa possível.[/quote]
Não que não devam existir outras classes, longe disso. A ideia é transformar um POJO “burro” em um VO útil e devidamente encapsulado. No caso essa outra classe seria um BO (Business Object), mas eu não acho legal, pois se uma classe pode fazer “o que bem entender” com esse objeto, outras classes também poderão, e ai temos um encapsulamento falho e vazado.
Sim, essa questão é bem mais complicada, quanto ao que o $ERVER colocou, existem soluções que conseguem garantir a integridade das nossas classes… Eu nunca recebo uma classe do tipo entidade diretamente nos controllers, para evitar o mass assignment. Uso sempre os DTOs que conseguem fazer esse trabalho…
Rafael Guerreiro,
Achei bem interessante os DTOs. Devemos implementar manualmente, ou existe alguma ferramenta que ajuda na criação deles?
Caraca, quanto mais eu estudo OO eu vejo que ela tá indo pro saco mesmo, pois quando é resolvido um problema dela, aparecem N outros. Ao menos é o que me parece no pouco tempo que tenho.
Abraços.
Não sei não, eu penso de uma forma parecida com o saoj a respeito de DTOs.
E, pela minha experiência, posso dizer, com todas as letras, que não existe bala de prata.
De qualquer forma, essa discussão vai acabar como as que são realizadas em torno dos DAOs…
[quote=$ERVER]Rafael Guerreiro,
Achei bem interessante os DTOs. Devemos implementar manualmente, ou existe alguma ferramenta que ajuda na criação deles?
Caraca, quanto mais eu estudo OO eu vejo que ela tá indo pro saco mesmo, pois quando é resolvido um problema dela, aparecem N outros. Ao menos é o que me parece no pouco tempo que tenho.
Abraços.[/quote]
Vamos lá, EU desconheço ferramentas e crio manualmente… Não vejo problemas nisso.
Um exemplo de como eu trabalho com DTOs:
public class User { // Entidade
private String username;
private String password;
private String name;
// Métodos que sabem o que fazer com cada DTO dos listados abaixo...
}
public class SignInUser { // DTO para a funcionalidade de login
private String username;
private String password;
}
public class UpdateUser { // DTO para a funcionalidade de alteração de dados cadastrais
private String nome;
}
public class ChangePasswordUser { // DTO para a funcionalidade de trocar de senha
private String oldPassword;
private String newPassword;
private String confirmNewPassword;
// Aqui faz validações de senha
}
A ideia, por exemplo, é evitar que o user consiga setar a propriedade password quando fizer uma requisição para trocar o username, somente…
Ou seja, se eu permito que a minha entidade seja setada “cegamente” pelos parametros passados pela requisição, eu posso permitir que ele sete coisas estranhas sem uma prévia validação.
Além de eu evitar que a minha action fique assim:
public void trocarDeSenha(String newPassword, String oldPassword, String confirmNewPassword){...}
Ela pode ficar um pouco mais elegante:
public void trocarDeSenha(ChangePasswordUser changePassword){...}
[quote=drsmachado]Não sei não, eu penso de uma forma parecida com o saoj a respeito de DTOs.
E, pela minha experiência, posso dizer, com todas as letras, que não existe bala de prata.
De qualquer forma, essa discussão vai acabar como as que são realizadas em torno dos DAOs…[/quote]
Muito interessante esse tópico…
Mas existe uma coisa que eu concordo com o saoj, “Camada de serviços só pode trabalhar com modelo, entidades reais, nunca DTO.”
Também concordo que não existe bala de prata, e sim, isso é uma discussão que não vai ter fim, pois cada um trabalha do jeito que mais lhe convém.
Mas uma coisa para mim é fato: não gosto de expor minhas entidades, pois qualquer coisa que for feito nelas podem refletir no banco, causando problemas maiores.
Por isso, eu trabalho com DTOs dessa forma, o DTO chega na action e a entidade “absorve ele”…
[quote=Rafael Guerreiro][quote=drsmachado]Não sei não, eu penso de uma forma parecida com o saoj a respeito de DTOs.
E, pela minha experiência, posso dizer, com todas as letras, que não existe bala de prata.
De qualquer forma, essa discussão vai acabar como as que são realizadas em torno dos DAOs…[/quote]
Muito interessante esse tópico…
Mas existe uma coisa que eu concordo com o saoj, “Camada de serviços só pode trabalhar com modelo, entidades reais, nunca DTO.”
Também concordo que não existe bala de prata, e sim, isso é uma discussão que não vai ter fim, pois cada um trabalha do jeito que mais lhe convém.
Mas uma coisa para mim é fato: não gosto de expor minhas entidades, pois qualquer coisa que for feito nelas podem refletir no banco, causando problemas maiores.
Por isso, eu trabalho com DTOs dessa forma, o DTO chega na action e a entidade “absorve ele”…[/quote]
Muito interessante esse tópico.
Rafael Guerreiro, você possui algum pequeno projeto que demostra a aplicação desses conceitos, que possa disponibilizar aqui o link??
Até mais.
Rafael Guerreiro,
Muito interessante. Você teria algum link de artigo ou qualquer coisa dando exemplos de uso de DTO e camadas de serviço também? Encontrei alguns mas parecem ser meio estranhos.
Obrigado.
Refazendo a pergunta: pra que serve a camada de serviço?
Obrigado, abraços.
[quote=douglas_arantes]Muito interessante esse tópico.
Rafael Guerreiro, você possui algum pequeno projeto que demostra a aplicação desses conceitos, que possa disponibilizar aqui o link??
Até mais.[/quote]
Olá Douglas, infelizmente eu não tenho nenhum projeto open source desse jeito… =/
[quote=$ERVER]Rafael Guerreiro,
Muito interessante. Você teria algum link de artigo ou qualquer coisa dando exemplos de uso de DTO e camadas de serviço também? Encontrei alguns mas parecem ser meio estranhos.
Obrigado.[/quote]
Na verdade muita coisa eu aprendi nesses cursos da Caelum, pode parecer merchan, mas eu recomendo fortemente. Tem também o Caelum Online que é uma versão minimalista do que passamos na sala de aula.
Acho que vale muito a pena investir em conhecimento, sendo que você pode vir a ter um cargo melhor…
[quote=$ERVER]Refazendo a pergunta: pra que serve a camada de serviço?
Obrigado, abraços.[/quote]
Tem uma coisa engraçada ai, eu só uso a camada de serviços em casos extremos…
A minha ideia é simples, cada classe tem um nome, esse nome diz o que ela faz. Se tem algum método fazendo algo que contradiz com aquele nome, ele é movido para alguma classe que faça sentido ou ele ganha uma classe só para ele…
A galera tenta economizar a criação de classes, eu acho isso horrível, quanto mais classes BEM FEITAS, mais específico estão suas classes, mais fácil de testar e de dar manutenção…
É comum eu criar muitas classes para problemas pequenos, algumas vezes o código fica tão bem separado que eu consigo fazer funcionalidades completamente genéricas.
Resumindo: eu corro de Services, Utils, POJO, Classes grandes, métodos com mais de 10 linhas, métodos que fazem mais de 1 coisa.
Existe uma colinha bem legal: se o nome da classe/método precisar de um E, está na hora de separar… Um exemplo tosco:
public void validaESalva(ClasseMarota cm) {
// Implementa o código de validação
// Manda o hibernate salvar no banco de dados
}
public void valida(ClasseMarota cm) {// Esse cara fica na classe que faz sentido tê-lo... Eu faria na própria entidade...
// Implementa o código de validação
}
public void salva(ClasseMarota cm) {
// Chama o valida
// Manda o hibernate salvar no banco de dados
}
[quote=Rafael Guerreiro]
Resumindo: eu corro de Services, Utils, POJO, Classes grandes, métodos com mais de 10 linhas, métodos que fazem mais de 1 coisa.[/quote]
Isso me leva a perguntar, você trabalha com o que mesmo?