Como usar Transfer Object?

Entendi, mas uma solução parcial não me parece suficiente:

[code]
// considerando que não precise retornar a pk
public void saveOrUpdate() {
for(Observer observer : myObservers)
observer.notify(this);
}

public void delete() {
home.delete( this );
}

public void load() {
home.load( this );
}[/code]

Mas com certeza há alguma maneira de abstrair isso. Não vale AOP XD

Uhmm…tem razão quanto ao delete.

Agora, query só pedindo rpo repositorio IMHO

Com certeza, senão fica uma zona. Criar um layer de abstração desse jeito seria besta:

[code]
class Repository {
public void updateAccounts( BugBear bugBear ){ … }
}

class UselessAbtractionLayer {
public void updateAccounts( BugBear bugBear ) {
repository.updateAccounts( bugBear );
}
}

class BugBear {
public void updateAccounts() {
uselessAbtractionLayer.updateAccounts( this );
}
}[/code]

Lipe,

ahmm… Eu apenas gostaria de registrar aqui minha insatisfação com o uso indiscriminado do DAO pattern.

public class ScrublesDAO {

      public void save(Pojo object) {
             hibernate = getSession();
             hibernate.save(object);
             closeSession();
      }

      public void delete(Pojo object){
             hibernate = getSession();
             hibernate.delete(object);
             closeSession();
     }
(...)
}

public class BubblesDAO {

      public void save(Pojo object) {
             hibernate = getSession();
             hibernate.save(object);
             closeSession();
      }

      public void delete(Pojo object){
             hibernate = getSession();
             hibernate.delete(object);
             closeSession();
     }
(...)
}

Não é que DAO seja uma idéia ruim, mas a interface Session do Hibernate já nem tem funcionalidade suficientes para a maioria das necessidades de um DAO. IMHO, se você puder evitar utilizar um DAO (e usar uma entidade mais genérica) melhor, você não acha ?

Para as operações CRUD dá para generalizar sim, ainda mais com Generics como o cv mostrou :smiley:

Mas não me lembro de criar um DAO/Repository/WTFory só com esses 4 métodos hehe

Acho que a maioria dos DAOs se resumem a isto. Acho que você poderia querer fazer buscas para alguns objetos chaves. Nesse caso, você poderia utilizar uma classe para realizar as operações de busca. Se isto ainda não for suficiente, ou as operações CRUD forem mais complexas do que as descritas aqui, então o padrão DAO pode ser (muito bem) considerado.

Agora, eu nunca utilizei o generics e sempre consegui generalizar o CRUD (no hibernate), porque o parâmetro desses métodos no session é Object.

http://www.guj.com.br/posts/list/15/20668.java

Estava passando por um dilema sobre DTO.
Estava pensando em usar DTO’s dinâmicos ou DTH (Data Tranfer HashMaps)
Vi que é bem utilizado pelo pessoal lá fora

http://helpdesk.princeton.edu/kb/display.plx?id=9772

http://www.theserverside.com/discussions/thread.tss?thread_id=9154

Gostaria da opinião de vocês.

só pra dar seqüencia nesse tópico (que está muito, muito maneiro)

eu não gosto de nenhuma das duas idéias.

Em um projeto recente vi que a abordagem do DTH seria legal mas fiquei com receio de complicar muito o código e acabei optando por usar CachedRowSet que, ao meu ver, reduziria esse risco (Floyd Marinescu sugere isso como um pattern mas eu nunca vi ninguém falando em CachedRowSet que não fosse a implementação da sun).

desculpem se falei alguma m ok?
acabei de chegar por aqui.

Também gostaria de trocar idéias sobre isso.

Ressucitando o tópico…
Por que os DTH complicariam o código ?

[quote=okara]Ressucitando o tópico…
Por que os DTH complicariam o código ?
[/quote]
Porque você precisa de uma pensa de sets de uma lado e uma tonelada no outro?

Fora que DTH são um engodo, eles geram um tráfego enorme de dados e consomem memória a rodo.

[quote=louds][quote=okara]Ressucitando o tópico…
Por que os DTH complicariam o código ?
[/quote]
Porque você precisa de uma pensa de sets de uma lado e uma tonelada no outro?

Fora que DTH são um engodo, eles geram um tráfego enorme de dados e consomem memória a rodo.[/quote]
Depende.

DTH são uma boa maneira de abstrarir os Beans entre as camadas. E se o trabalho de gerenciar os HashMaps for bem feito (leia-se, o programador não precisa fazer nada) eu acho uma boa alternativa.

Tem como dar um exemplo disso ?

[quote=okara][quote=‘marcelomartins’]
DTH são uma boa maneira de abstrarir os Beans entre as camadas. E se o trabalho de gerenciar os HashMaps for bem feito (leia-se, o programador não precisa fazer nada) eu acho uma boa alternativa.
[/quote]

Tem como dar um exemplo disso ?[/quote]
Não consegui pensar em nada simples para te exemplificar, então imagina no teu sistema web tu não quer que o JSP conheça tuas classes do dominio.

Então, antes de chegar no JSP uma classes de infraestrutura (framework) ve todos as classes que estão populadas e transforma para HashMaps. No JSP dá pra trabalhar como se fossem as classes no lugar dos HashMap, é transparente.

Não sei se fui bem claro, mas foi uma tentantiva. :wink:

Você transporta os objetos em forma de hashmaps ?
É isso ?
Mas que vantagem isso teria ?
Eu teria que distribuir os pojos (DTO’s) do mesmo jeito.
Então é melhor transportar pojos.

A vanategm é que você nãp criaria uma classe DTO por objeto, mas a pergunta seria:

Mas porque usar um DTO neste caso em primeiro lugar?

http://fragmental.com.br/wiki/index.php?title=Evitando_VOs_e_BOs

Excelente compilação, shoes. Obrigado :smiley:

Senhores,

  Parabéns pelo excelente fórum e pela discussão em alto nível. 

  Gostaria de colocar algumas "gotas de pimenta" na conversa.

  Desenvolvemos aqui na empresa alguns sistemas usando CMP 2.0 e posteriormente começamos a utilizar o Hibernate como framework de persistência. Nos primeiros sistemas fizemos uso intensivo de DTOs e nos sistemas Hibernate passamos a utilizar os próprios Domain Beans. Só pra contextualizar, as aplicações são divididas em camadas, onde os canais de interface com o usuários são desenvolvidas e implantadas em aplicações independentes das aplicações de negócio. Exemplo, aplicações clientes WEB e SWING, com as aplicações servidoras distribuídas através do uso de EJBs. 

  Alguns pontos sobre o uso dos Domain Beans como moeda de troca dos métodos com as aplicações clientes: 

 1. As aplicações se tornaram dependentes da solução de persistência. A biblioteca do Hibernate passou a ser necessária na implantação das aplicações clientes. Ou seja, se eu uso um TomCat para implementar minhas aplicações WEB preciso anexar o jar do Hibernate a um container que é somente WEB.

 2. Os Domain Bean Hibernate (pois eles passam a ser objetos Hibernate) quando enviados ao cliente são passíveis de lançarem exceções Hibernate. Por exemplo, um objeto A que possua uma coleção de objetos B ( tipo Funcionário com Dependentes) e cuja a associação está marcada com LAZY. Neste caso, se o programador da aplicação cliente tentar acessar a coleção de Dependentes recebe uma exceção Hibernate avisando que não é possível "carregar" os objetos pois estão fora do "contexto" do Hibernate.

Esses problemas sempre me remetem a questão do isolamento entre as camadas. Mesmo não trabalhando com sistemas distribuídos (SOAP, RMI, CORBA) a separação lógica entre as camadas do seu sistema devem continuar a existir e não me parece uma boa prática enviar objetos Hibernate ou EJB3 para uma página JSP. Como também o contrário, e muito mais fácil de ser percebido como uma prática ruim,  enviar para as camadas de négocio da aplicação,  objetos Struts (como os objetos que estendem o ActionForm) ou objetos que lidam com o protocolo HTTP como os HttpServletRequest. 

Me parece bastante claro os objetivos de uma aplicação cliente: coletar e exibir dados. Nada mais. O fato de enviar um Bean “parrudo”, cheio de “regras de negócio” acredito que apenas dificulte o trabalho de quem implementa a aplicação cliente. Na grande maioria das vezes você precisa
contextualizar as suas regras de negócio ao escopo de uma transação, fora dela você está sujeito à inconsistências. A lógica de cada caso de uso faz parte da solução do sistema e deve ser descrita na aplicação servidora. Muitas das vezes apenas com os dados “inputados” pelo cliente o estado do objeto ainda se encontra “incompleto”, e que só vai ser “terminado” durante o decorrer da transação na aplicação servidora. Não adianta portanto que os “sets” ou os “validates” sejam executados pela aplicação cliente. É uma função dos componentes de sistema e dos componentes de domínio (vide UML Components - Cheesman).

Quanto a grande dificuldade de criar e manter DTOs, não vejo dessa forma. Exite uma classe (como a maioria das fornecidas pela Apache) que é a BeanUtils, que tem um método muito útil chamado copyProperties(). Com ele é possível facilmente popular os Domain Beans a partir dos Forms e/ou HashMaps e vice-versa. Quanto a gerar e regerar os Assemblers e os próprios DTOS, a maioria das IDEs já faz isso pra você.

Outra coisa, Beans simples normalmente são usados para telas de cadastro. Em grande parte dos casos de uso os objetos que chegam a aplicação cliente são mais complexos. Vide telas de consulta onde normalmente lidamos com “resultsets”, ou grafos de objetos.

Bom, acho que to escrevendo demais … STOP. :smiley:

Abração.

Oi, Renato,

Isso indica que você não está utilizando separação de Camadas. A Camada de Persistência é a única que deve (pode, na verdade) depender do Hibernate, se seu Tomat não é responsável pela persistência provavelmente você tem um problema de arquitetura.

Novamente vejo um problema de arqutietura aqui. Seus objetos persistidos pelo Hibernate deveriam ser POJOs, eles não podem depender do Hibernate. Essa dependência é um erro de projeto.

Este é um problema de Lazy-Loading, você tem opções para gerenciar este problema na Camada de Persistência ou simplesmente não utilizar este recurso.

Como falei antes este é o problema desta arqutietura: não existe separação de Camadas. Você está deixando lógica de persistência escorrer para a Camada de Negócios e isso não é culpa do framework :wink:

Exato e não há porque você fazer isso com Hibernate.

Para isso existem DTOs, que sao um conceito diferente de TO(antigo VO) ou até de objetos burros.

Não entendi o que isso tem a ver com TO/VO.

Hmm… Cheesman? Deixa eu adivinhar: CCE da PUC-Rio?

Uma biblioteca extra só para criar objetos burros? Acho que não condiz muito com OOP.

De qualquer forma o problema não é copiar dados apenas, é manter hierarquias paralelas artificiais de objetos.

Existem dezenas de maneira de lidar com isso num domínio rico, não vejo qual o problema.