Classes de dados e classes de lógica

Para mim a idéia acima parece se confrontar com o princípio OO de “colocar dados e operações sobre os mesmos na mesma classse”, ou seja, de criar objetos inteligentes o que pelo o que entendi tornaria seu uso mais intuitivo. A idéia acima talvez pareça tender para criar beans burros e classes estáticas, soando meio estruturado (meu entendimento atual é que nesse caso isso não se aplica). Estou meio confunso e gostaria da opinião de vós outros.

Meu pensamento atual a respeito é essa visão “banco-de-dática” onde eu simplesmente crio beans burros (ou cuja inteligência não gere acoplamento) que são tipo “wrappers” das tabelas do banco, como Micro, Software, Manutencao, Fabricante etc., apenas (ou basicamente) para guardar informações e representar as entidades do banco. Então em cima disso, separadamente eu crio as classes de lógica, como GerenciadorMicros, sei lá, que realizarão operações com as “classes de dados”. Além de não achar que, nesse caso, estou contrariando o princípio OO citado acima, o principal benefício dessa estratégia pra mim é diminuir o acoplamento do sistema. Sendo mais gerérico, para decidir se “separo os dados da lógica” ou não, eu uso as seguintes observações:

  1. Os “dados” representam uma entidade informativa fortemente caracterizada (caso dos “wrappers” de tabelas), ou seja, essa entidade existe por si só, independentemente de lógicas que lhe sejam aplicadas:

Neste caso vou modelá-los como “classes de dados” *, e poderão existir N lógicas que posso aplicar sobre estas classes, compartilhando-as.

  1. Os dados representam informações de estado ou suporte a uma classe de negócios (não especificamente de aplicações de banco de dados), ou seja, elas só têm sentido se associadas a uma determinada lógica, e não como representantes de uma entidade de informação existente por si só:

Neste caso não vou criar uma classe separada com os dados, vou colocá-los juntos com a classe de lógica, pois os dados são uma característica, uma propriedade da classe.

O que acham?

[size=10]* Entrando no assunto deste tópico, essas “classes de dados” é pelo o que entendi o que muitos confundem com DTOs, sendo que não acharia VO uma classificação ruim apesar de desnecessária, pois acho “Cliente” melhor que “ClienteVO” (não sei a diferença entre DTO e VO, só ouço que são praticamente iguais). Certo?[/size]

Conceitualmente isso está errado.
Como vc disse pelo conceito OO devemos ter dados e operações juntos.

Mas funcionalmente isso é ideal na minha humilde maneira de ver.
Você tem separação das classes persistentes que representam as entidades e os processos.

Entre o conceitual e o funcional eu escolho o meio-termo.
E essa declaração me parece ter bom censo.
Eu adotaria…

Cara, você falou de acoplamento fraco, mas depois também falou:

No fim das contas você vai se encontrar fazendo isso aqui

public class FuncionarioManager {
    public FuncionarioManager( Funcionario func ) {
           func.getX();
           func.getY();
           func.getW();
           func.getGet();
           func.getGetter();

           func.setX( x );
           func.setY( y );
           func.setW( w );
           func.setSet( set );
           func.setSetter( setter );
   }
}

Por que não coloca tudo no mesmo lugar de uma vez? Se falar que é para aliviar a carga da rede, vou postar uma imagem aterradora.

O grande problema da modelagem é que temos que amarrar nossa lógica OO com o modelo relacional.

Não tem jeito gente. O modelo realcional é a melhor maneira de persistencia existente hoje.
Querendo ou não temos que adaptar nosso modelo OO para o relacional.
Por motivo de desempenho, reaproveitamento da lógica de dados, funcionalidades do sistema.

Esse é o grande problema ao meu ver. Sempre a gente tem que fazer alguma gambiarra.
Nós pensamos ainda com pensamento relacional, não adianta fugir.
Sempre iremos exergar “select * from…” ao inves de objeto.fazer();

Oi,

Eu já li coisas boas e ruins do lozano, tenho até o livrinho dele em java com GNU/Linux (despretencioso e bonzinho), mas realmente essa afirmação é mais um motivo para eu não comprar a Java Magazine este mês.

Vou dividir isso em duas coisas. primeiro: você precisa de um domínio de aplicação? Sim, essa é uma pergunta séria. Você pode não precisar e muitos aqui não precisam para muitas das coisas que fazem. Avaliar isso é difícil, se você chegou à conclusão que:

  • Não vai ter que dar manutenção
  • A aplicação é mais que simples, é idiota, do tipo tira e põe no SGBD
  • Tempo escasso

Faça como o Lozano sugeriu.

Se você está fazendo algo mais complxo, ou algo que vá evoluir, considere construir um projeto dividido em camadas e com um domínio bem projetado.

O domínio compreende objetos que representam entidades e valores no seu sistema, temos nossa classe Venda, por exemplo.

Acima da camada de domínio existe uma camada de aplicação. Nessa camada nós pdoeríamos oferecer, por exemplo, uma classe GerenciadorVendas (utilizando um Service Layer) com um método registrarVenda(). Este método é extremamente magro e só envia uma mensagem para os obejtos de negócio, criando um objeto venda, por exemplo.

Se eu rpecisar de uma funcionaldiade de relatórios, eu pdoeria criar uma classe GerenciadorRelatorio com método gerarRelatorioVendasMes(Mes mes) que estimulasse os objetos de negócio nesse sentido.

A camada de aplicação é muito importante para estimular os objetos de negócio, mas as regras de negócio estão nestes objetos. Essas classe sim não têm estado, mas as classes de negócio têm estado sim (é claro que existem casos onde não teriam, ams de uma maneira geral sim, teriam).

O que o Lozano propõe, me parece, é pura e simplesmente programação estruturada. Eu tenho minha “classe de informação”:

class Venda{
 private String codigo;
 private double valor;
 private Date data;
 private Cliente cliente;
 private Collection itens;
 //get/set...
}

E minha classe de “processo de negócio”:

public void registrarVenda(String codigo, double valor, Date data){
 Venda venda = new Venda();
 venda.setCodigo(codigo);
 venda.setValor(valor);
 venda.setData(data);
 cliente.addVenda(venda);
 venda.setCliente(cliente);
 ...
 persistenciaQualquer.salvar(venda);
 persistenciaQualquer.salvar(cliente);
}

public void cancelarVenda(Venda v, Cliente c){

 c.listarVendas.remove(v);
 persistenciaQualquer.deletar(venda);
 persistenciaQualquer.salvar(cliente);
}

Agora me digam: qual a diferença entre isso e programação estruturada?

Alguém sabe o mail do lozano? Ele pdoe se interessar pela discussão…

jprogrammer no seu outro tópico foram dadas sugestões para resolver este problema.

Não entendo por que vocês acham que é necessária uma classe só para persistência. A merda reside em como popular o objeto, mas este precisa de atributos não importa qual o mecanismo de persistência.

[quote=jprogrammer]O grande problema da modelagem é que temos que amarrar nossa lógica OO com o modelo relacional.

Esse é o grande problema ao meu ver. Sempre a gente tem que fazer alguma gambiarra.
Nós pensamos ainda com pensamento relacional, não adianta fugir.
Sempre iremos exergar “select * from…” ao inves de objeto.fazer();

[/quote]

Mapeamento Objeto-Relacional é uma droga, mas o problema não é tão grande assim. De repente esse texto (ou outro desse site/livro) te ajuda.

O grande mal do mapeamento é que você vait er que expôr seu estado para que seja persistido. Existem diversas formas de amenizar o rpoblema (como usar múltiplas interfaces para múltiplos clientes), mas essa limitação não afeta o princípio geral das coisas, de que um objeto deve ter estado e comportamento.

Nova recomendação de leitura do Shoes:

Eu estou convencido e não tenho mais dúvidas enquanto isso.
É apenas uma observação pessoal de que é difícil modelar OO se baseando na estruturada.
É uma coisa de cultura.
É difícil largar os velhos conceitos.
Mas muitas vezes é a própria teconologia que nos limita…

Olá,

[quote] Nós pensamos ainda com pensamento relacional, não adianta fugir.
Sempre iremos exergar “select * from…” ao inves de objeto.fazer(); [/quote]

Estou tentando evitar isto, mas o problema de performance, em ter que instanciar classe por classe (via construtor-negócio -> contrutor-banco -> contrutor-negócio ) está me forçando a pensar estruturado novamente.

Márcio

Lipe posta aquela imagem porque realmente eu fico pensando se “objetos inteligentes” são mais “gordos”, mas custosos de enviar pela rede ou mesmo instanciar. Ainda não tirei nenhuma conclusão, estou meio confuso ainda.

Na verdade, é o contrário. objetos magros são mais caros de passar, proque geralmente um objeto magro tem associações mil com um onte de gente, e você vai precisar utilizar estas associações. Cada vez que você precisa, você faz uma chamada RPC bem cara para executar uma coisa a toa, por isso é mais prático embrulhar tudo e mandar de uma vez na rede :wink:

Estou completamente errado ou a sugestão do Lozano é que devemos utilizar Anemic Domain Model? http://www.martinfowler.com/bliki/AnemicDomainModel.html

[]'s
Marco Campêlo

marcioa1
Apesar de estar convencido sobre os benefícios OO.
Eu também penso nisso diariamente…
Não sei se não se estão nos vendendo modismos…
Quando vejo aplicações estruturadas super robustas e escaláveis fico com uma saudade.

[quote=pcalcado]
Alguém sabe o mail do lozano? Ele pdoe se interessar pela discussão…[/quote]

fernando@lozano.eti.br

[]'s
Marco Campêlo

Ah Márcio cê taí! Nem continuou naquele tópico de performance hein? Parecia que cada instanciação executava um select diferente na mesma tabela…Posta lá, responde!!

[quote=Email]Phillip Calçado to fernando
More options 11:02 am (34 minutes ago)
Olá, Fernando,

Estamos discutindo no GUJ um texto seu na Java Magazine deste mês
(creio). Se quiser dar uma olhada e responder, seria muito bom para
trocarmos experiências.

O thread está em:

http://www.guj.com.br/posts/list/23735.java

[]s


Phillip Calçado
ICQ: 1110nine38six5
M$N: pcalcado@gmail.com
Y!: pcalcado@yahoo.com
http://www.jablo.com.br/blogs/page/pcalcado
http://www.jroller.com/page/pcalcado
Crux Sacra Sit Mihi Lux[/quote]

Você pediu pela imagem: medo

Ainda não consigo entender a diferença entre ter uma classe com dados e lógica e ter duas classes, sendo que uma fica fazendo get e set pra todo lado. Alguém sabe me explicar a vantagem da segunda maneira?

Tente isso aqui.

Esse cara é corajoso !!!

O problema é como um ex professor que trabalhava em uma dessas consultorias bam-bam-bam falava tem gente que exige a metodologia RUP, mas não sabe o que é RUP.
Eu quero RUP porque é bom.

Outra coisa que ele metia o pau era a metodologia “hibrida”.
meia-estruturada meia-OO.
É o que o pessoal anda fazendo.

O artigo do Lozano tem uns três meses.

O problema é que fazendo a parada ficar mais OO, mais intuitiva, parece que a “identidade” do banco fica meio perdida. Parece que dificulta reuso e divisão de responsabilidades, gera acoplamento. Por outro lado, as classes ficam meio “soltas”, menos coesas e intuitivas. É um dilema!

Uma coisa interessante seria criar uma classe de dados e extendê-la com lógica de negócio:

class DadosCliente {
    String nome, endereco;
    int idade;
}

class Cliente extends DadosCliente {

    List<Venda> vendas; 

    public List<Venda> getVendas(int ano) {
        // tralálá
        return vendasNoAno;
    }

    public boolean isChato() {
        return this.mediaLigacoesSACNoMes() > 4
    }

}

Desse modo eu poderia reutilizar a classe de dados com outra lógica, criando uma nova sub-classe. O que acham?