Qual a maneira correta para fazer POJO's

[quote=drsmachado][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?[/quote]
Com Java… É Orientação à Objetos…

Usar Services, Utils e POJOs “burros” só significa que o código está errado de alguma forma… Mas é lógico que existem exceções.

O clássico StringUtils, por exemplo, nós precisamos usá-lo pois não podemos extender String e fazer com que implemente esses métodos para nós.

Repare que a maioria dos métodos “utils” da vida são static… Se está usando static, também significa que o código está errado de alguma forma. O static força você a voltar para o procedural.

Existem vários Design Patterns que auxiliam a gente a fazer um código decente colocando as regras de negócio em classes decentes.

Por exemplo, você deixaria um método no Service cheio de ifs ou preferiria usar um strategy para eliminar esses ifs?

[quote=Rafael Guerreiro][quote=drsmachado][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?[/quote]
Com Java… É Orientação à Objetos…

Usar Services, Utils e POJOs “burros” só significa que o código está errado de alguma forma… Mas é lógico que existem exceções.

O clássico StringUtils, por exemplo, nós precisamos usá-lo pois não podemos extender String e fazer com que implemente esses métodos para nós.

Repare que a maioria dos métodos “utils” da vida são static… Se está usando static, também significa que o código está errado de alguma forma. O static força você a voltar para o procedural.

Existem vários Design Patterns que auxiliam a gente a fazer um código decente colocando as regras de negócio em classes decentes.

Por exemplo, você deixaria um método no Service cheio de ifs ou preferiria usar um strategy para eliminar esses ifs?[/quote]
Pergunto pois suas respostas me levam a crer que você jamais teve que dar manutenção em código legado.
Ou até, nunca teve de desenvolver um sistema onde as regras de negócio possuem complexidades extremas.

Já tive, como tenho.

Estou cheio de classes com regras de negócio complexas ao extremo, como sistemas de faturamentos…

Consegui graças ao TDD… Sim, eu faço testes.

Quanto ao código legado, é só começar a escrever testes para eles, refatorar e eles deixam de ser legados. Que é uma das boas práticas ao dar manutenção em código legado (leia-se código sem testes)…

Além de estarmos falando sobre maneiras corretas de fazer algo, e não maneiras legadas/fáceis/faz como dá…

Rafael Guerreiro, então eu deixaria de usar o objeto que era POJO e coloco o DTO no model disponibilizado pra página?

Um exemplo - pegando um objeto da classe Conta e exibindo numa jsp:

[code]public class Conta{

private String numero;
private double saldo;

public Conta() {

}

public void sacar(double quantia) {
if (quantia <= saldo) {
saldo = saldo - quantia;
}
}

public void depositar(double quantia) {
saldo = saldo + quantia;
}

//nada de getters e setters que já não são mais necessários para o framework

}[/code]

Eu não entendi como ficaria o DTO para cada funcionalidade. Seria um DTO para o método sacar e outro para depositar?

Quanto aos cursos das Caelum, quero fazer o fj21 ainda esse ano, me parece realmente muito bom. Concordo contigo, isso é investimento.

Muito obrigado pela atenção, abraços.

Rafael Guerreiro, usando seu exemplo:

[code]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
} [/code]

Onde e como eu colocaria os métodos para exibir o nome e user name do usuário numa jsp?

Obrigado, abraços.

As classes ervece não fazem mais ou menos isso também?

Se você estiver 2 telas separadas, por exemplo, eu classifico como 2 funcionalidades, então sim, são 2 funcionalidades separadas…

Nesse caso eu uso o POJO mesmo, somente em casos onde eu serializo para JSON que eu uso DTO.

Eu me preocupo com 2 coisas: objetos preenchidos pelos dados que o usuário colocou no form e com serialização JSON…

Então, eu não me preocuparia com os getters (se fizerem sentido para você) na entidade, visto que estes não mudam o seu objeto (tome cuidado com a mutabilidade).

Mas então a minha lógica na classe Conta iria ser prejudicada. E se uso DTO com getters e setters, pra que o DTO? Acho que não entendi algo.

Agora acho que entendi, getter pode deixar pq não vai alterar o estado do objeto, portanto, não interfere nas regras de negócio. Mas mesmo assim ainda deixa um buraco: eles estão lá apenas pro framework - no meu caso - então a classe tem mais de uma responsabilidade - deixar os seus campos visíveis com os getters para o framework. O que você acha?

Acho que ainda não entendeu o principal ponto, vou fazer um exemplo clássico aqui:

public class Pessoa {
   private String nome;
   private String sobrenome;

   public String getNomeCompleto(){
      return nome + " " + sobrenome;
   }
}

Na hora de pegar esse objeto na JSP vc faz assim:

Ou seja, o ponto é que VOCE precisa desse getter e não o framework…

Agora entendi! O objeto precisa ter a responsabilidade de retornar o nome dele, é isso mesmo?

Só mais uma coisa:

Eu nunca usei classes service, mas pelo pouco que vi, me parece que elas fazem mais ou menos o que os seus DTOs fazem: validação. Tem diferença entre os dois?

Já vi alguns tutoriais na internet com classes do tipo ClienteService, que faziam a validação do Cliente antes de inserir no banco ou qualquer outra coisa.

Nesse exemplo:

[code]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
} [/code]

Não seria melhor, isso?

public class SignInUser { // DTO para a funcionalidade de login private User user; }

Não tem diferença olhando apenas esse ponto.

Os meus DTOs são usados para as validações… Mas, se fizer sentido, ele pode validar-se sim…

O ponto do Service e do Utils é que são classes “faztudo”, então, muitas vezes vc coloca métodos lá que não fazem sentidos.

Olhe a diferença entre 2 Services:

public class UserValidator {
// valida os dtos referentes aos usuários
}

public class UserService {
// valida os dtos referentes aos usuários
}

O NOME da segunda classe te diz que ela pode fazer muito mais que apenas validações. ESSE é o real problema.

A gente pode ter Utils, mas dê um nome decente à ele que diga que ele só pode fazer determinada ação.

O problema é que vc vai precisar implementar alguma coisa e vai tacar no UserService por que ele faz de tudo mesmo… Ai vc tem uma classe gigante e lotada de dependências, ou seja, uma classe mal planejada.

Eu acho que entendi. Vejamos:

DTO - ou Data Transfer Object - não o que eu pensava: um objeto usado apenas para pegar os dados - de um DAO, por exemplo - para disponibilizar para as jsp. Quem tem a responsabilidade de disponibilizar os valores dos seus campos é a própria classe - através dos métodos getters.

Tudo isso trata mais de conceito do que implementação mesmo? Tipo, eu devo separar melhor o que cada classe minha faz? Se preciso validar um login de usuario, crio uma classe LoginValidator, se preciso de validação pra alteração de senha, crio uma classe AlteracaoDeSenhaValidator?

Por um lado acho bem interessante, mas você percebeu que tudo isso trata apenas da parte estrutural de um sistema, não tendo nada a ver com o negócio?

E mais uma pergunta: nos meus controllers eu não devo nunca usar uma entidade (classe que tenha regras de negócio) diretamente, sempre usar um DTO pra validar quando os dados vem do usuário?

E se não vier do usuário, posso usar uma entidade (classe que tenha regras de negócio) diretamente?

[quote=$ERVER]Não seria melhor, isso?

public class SignInUser { // DTO para a funcionalidade de login private User user; } [/quote]
Não… Visto que eu posso setar qualquer propriedade do user que está dentro do DTO… Se você for fazer isso, é melhor que nem tenha o DTO…

[quote=$ERVER]Eu acho que entendi. Vejamos:

DTO - ou Data Transfer Object - não o que eu pensava: um objeto usado apenas para pegar os dados - de um DAO, por exemplo - para disponibilizar para as jsp. Quem tem a responsabilidade de disponibilizar os valores dos seus campos é a própria classe - através dos métodos getters.

Tudo isso trata mais de conceito do que implementação mesmo? Tipo, eu devo separar melhor o que cada classe minha faz? Se preciso validar um login de usuario, crio uma classe LoginValidator, se preciso de validação pra alteração de senha, crio uma classe AlteracaoDeSenhaValidator?

Por um lado acho bem interessante, mas você percebeu que tudo isso trata apenas da parte estrutural de um sistema, não tendo nada a ver com o negócio?[/quote]
Sim, está tudo certo. Sim, é parte estrutural mesmo, é uma questão de organização de classes.

Sim, eu faço isso.

Sim, também. Desde que você saiba que quem está mexendo nessa entidade não vá estragar tudo…

Rafael Guerreiro,

Muito obrigado pela aula! Tirou todas as minhas dúvidas!

Grande abraço.

Rafael Guerreiro,

Já usou o Spring MVC? Ele usa os métodos setters para fazer o binding da visão com o modelo. Nesse caso sou obrigado a mudar de framework?

Abraços.

Segue um artigo sobre o assunto: http://www.arquiteturajava.com.br/livro/cuidado-com-o-modelo-anemico.pdf

Muito bom!