Mais Sobre Melhores Práticas com TO

Olá GUJ’s…

No projeto de final de curso da faculdade estamos utilizando o TO para tranferir dados entre camada de controle e negócio. Já a troca de dados entre camada de apresentação e controle tenho algumas dúvidas mas postei essas dúvidas aqui no GUJ neste endereço…

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

Agora gostaria de entrar em alguns detalhes de implementação do TO.

No meu projeto estou utilizando na camada de negócio os patterns.

[list]Façade[/list]
[list]Application Services[/list]
[list]Businnes Objects (BO)[/list]
[list]Transfer Objects (TO)[/list]
[list]Data Access Objects (DAO)[/list]

Em geral, é no façade onde a histório começa recebendo um TO por parâmetro… e ele por sua vez quando precisa retornar dados para a camada controle sempre vai retornar um TO.

Mas a minha dúvida principal é:
Qual é a melhor forma para converter um BO em um TO e vice versa??? Vou listar abaixo algumas sugestões que andei pensando, daí eu gostaria da opinião e sugestões de vocês se for possível.

Opção 1: Utilizar um método setData e getData dentro do BOfortemente acoplado com código de conversão.

public class AlunoBO {
    
    // atributos

    // métodos acessores

    // método para converter TO para BO
    public void setData(AlunoTO to) {
        // conteúdo do método para conversao
        // exemplo : this.atributo = to.getAtributo();
    }

    // método para converter BO para TO e vice versa
    public AlunoTO getData() {
        // conteúdo do método para conversao
        // exemplo : to.setAtributo(this.atributo);
        return to;
    }
}

Opção 2: Utilizar método setData e getData dentro do BO, no entanto, com o código de conversão dentro de uma classe separada responsável somente pela conversão.

public class AlunoBO {
    
    // atributos

    // métodos acessores

    // método para converter TO para BO
    public void setData(AlunoTO to) {
        // Chama uma classe responsável pela conversão
        AlunoConversao alunoConversao = new AlunoConversao();
        this = alunoConversao.convertoParaBO(to);
    }

    // método para converter BO para TO e vice versa
    public AlunoTO getData() {
        // Chama uma classe responsável pela conversão
        AlunoConversao alunoConversao = new AlunoConversao();
        alunoConversao.convertoParaTO(this);
    }
}

Opção 3: Eliminar os métodos setData e getData do BO. Toda a conversão deverá ocorrer no ApplicationService, Action, Command ou Façade.

public class AplicacaoFacade {

    // método para converter TO para BO
    public void cadastraAluno(AlunoTO to) {
        AlunoBO bo = new AlunoBO();
        AlunoConversao conversao = new AlunoConversao();
        bo = conversao.converteParaBO(to);
        
       // realiza outras atividades 

    }
}

Bom, essas são as opções que pensei… Eu aprecio mais a terceira opção, mas como sou inexperiente, acredito que você devem ter terceiras, quartas, quintas e até vigésimas opções!!!

Desde já agradeço!
Thiago Senna

Voce precisa de todos esses objetos auxiliares mesmo? Pq, se consistirem basicamente nas mesmas propriedades, eh meio overkill vc ter esse trabalho todo.

Rafael

Olá Rafael!!!

Bom… eu coloquei tudo isso de patterns realmente para aprender, já que o mercado aprecia profissionais com conhecimento em patterns… por isso fiz um overload de patterns no projeto… hehe!!!
Eu estava imaginando que as soluções fossem boas… mas esse é meu ponto de vista!!! Por isso preciso da opinião de vocÊs que já tem vivência no assunto.

Quando você diz Overkill quer dizer que tem muitas Muita classe, muito pattern??? Quais serão as consequências deste overkill???

Um Abraço!
Thiago

quanto mais objetos, “teoricamente” mais pesada ficara sua app.
o que me parece como o Rafael disse, que seus To’s e BO’s parecem ter a mesma finalidade, encapsular os dados.
acho que DAO -> TO -> FACADE - > BUSINESS DELEGATE -> VIEW, usando o TO para transferir os dados pelas camadas, seriam suficientes.
Mas isso depende de cada caso.
Eu gosto por exemplo, de em vez de criar varios TO’s, eu crio um unico, que é um hashmap, e sempre uso ele.em compensação tenho varios arquivos para definir as chaves desse objeto.
depende muito do caso.
flw!

[]'s

Deixe-me aproveitar o gancho e tirar uma outra dúvida.

Implementei algumas coisas usando esta estrutura usando TO, BO e Façade, mas eu senti que muitas vezes o BO é desnecessário. Só o TO já é o suficiente para fazer o cadastro de um aluno.

Mas quando há cálculos, relacionamentos e etc??? Por exemplo, suponha que você tenha que calcular a média final do Aluno.

Então esse tipo de método não pode ficar no TO, mas sim no BO!!!

MInha pergunta é: Eu deveria realizar a conversão de TO para BO só quando fosse realmente necessário… ou seja, em casos onde eu precisasse e dependesse de métodos de negócio ou relacionamento com outras classes???

Valeu!
Thiago

Nao somente isso, mas tambem a real necessidade de ter um TO / DTO alem das entidades normais. Por exemplo, se vc tem

class Noticia {
    id, texto, titulo, data;

    // get / set
}

class NoticiaDTO {
    id, texto, titulo, data;

    // get / set
}

eh algo que somente ira adicionar camadas a mais / complexidade desnecessaria na sua aplicacao, ja que vc tem que ficar mantendo varias classes com praticamente a mesma finalidade. Talvez o DTO tenha ligeiramente mais ou menos campos, ou entao a entidade tenha um ou outro metodo que o DTO nao precisa, mas se isso nao tiver um impacto profundo na performance / se realmente nao for viavel usar a classe “normal”, entao o DTO acabaria sendo um tanto dispensavel.

Por outro lado, ja que vc esta fazendo testes para entender melhor como tudo funciona, nao teria mto pq se prender em tais “detalhes” nesse momento. Faca usando a sua abordagem inicial, e depois tente outras, mais simples, e veja o resultado.

Rafael

suas regras de negocio podem estar por exemplo dentro do(s) facade(s), onde vc chamaria os dao’s necessarios e retornaria o objeto de resultado.
somente os facades conhecem a sua forma de persitencia(DAO’s), e os facades seriam invocados por exemplo por BusinessDelegate, que não teriam regra de negocio, somente fariam o lookup do facade e executariam os metodos.
ainda acho os seus BO’s com a mesma função dos TO’s, ou não estamos falando da mesma coisa…

[]'s

Olá

Os patterns surgiram da necessidade de compartilhar soluções. Para compartilhar alguma coisa é preciso uma linguagem comum e uma das características importantes dos patterns é o nome.

Agora vamos imaginar uma equipe nova que procura se familiarizar com patterns e ainda está aprendendo os nomes que se confundem porque alguns deles as vezes mudam de nome.

Aí vem alguém e começa a chama-los por siglas como foi o caso do título deste tópico. Ora, quem aprendeu o nome Data Transfer Object pode ficar completamente perdido. Então vai procurar no google e acaba encontrando com o diabo do Bush. Vejam o primeiro link que aparece no google quando a gente procura por to:
google

Sugiro fortemente que use o nome completo do pattern.

[]s
Luca

Olá Lucca!

Depois deste post acho que nunca mais vou colocar apenas a sigla do Pattern!
Valeu mesmo pelo toque!

Quanto aos outros posts acho que terei que concordar com vocês!!!
Estou convencido…

Mas com tudo isso acho que talvez o meu maior problema seja ainda não conhecer realmente bém os Padrões DAO e Façade! Melhor dizendo… acho que não conheço nenhum pattern realmente bém!

FArei o seguinte. Começarei o projeto com a dica que o Rafael passou… ou seja, desenvolva com a idéia inicial. No entanto, durante o início do projeto ficarei atento as experiências que vocês postaram neste tópico, e de acordo eu for sentindo as dificuldades e for aprofundando meus conhecimentos nos padrões de projeto, tentarei encorajar minha equipe de projeto para fazermos um refactoring, e de pouco em pouco, sentindo os desafios e a complexidade inicial, iremos mudando para uma solução mais viável conforme vocês do grupo opinaram.

Bom, pelo que vi, acho que em breve colocarei outros posts sobre Façace, DAO e etc…

Estou muito grato pela atenção do grupo!
Um Abraço!
Thiago Senna

Mini dicionário deste tópico:

DAO -> Data Access Object
DTO -> Data Transfer Object (TO para os íntimos)
FACADE -> Fachada mesmo
BUSINESS DELEGATE -> clica aqui
VIEW -> visualização

Geral: http://c2.com/cgi/wiki?DesignPatterns

Uma imagem vale mais que mil palavras!

:XD:

Se você colocar a regra de negócio do seu sistema num Façade e/ou achar que apenas DTOs (ou Data Transfer Objects :slight_smile: ) são suficientes, você nãoe stá trabalhando com um modelo Orientado a Objetos, mas sim algo imensamente procedural.

Pense numa coisa: se você fosse reescrever isso numa linguagem procedural (e.g. C), você substituiria os métodos no façade por funções e os DTOs por registros e… pronto.

Se isso é o que você quer ou não, não sou eu quem vai dizer, mas num modelo de objetos, você deve definir um conjuntod e objetos de domínio. DTOs são uma gambiarra (procure “gambiarra” no fórum para char milhões de posts sobre DTOs) e nãod evem ser usado fora de situações extremas.

Crie objetos com comprotamento e atributos, não apenas um bando de dados agrupados que vão e vêm do SGBD. Não crie objetos por funcionaldiade. Crie objetos no seu sistema, que representam as entidades dele.

Olá,

Assim como o Phillip e mais alguns aqui do forum eu nao gosto do uso de DTO, a nao ser que isso seja totalmente indispensavel (entenda como um objeto muito grande precisa ser trafegado pela rede). Entao eu sugiro alguns estudos a mais. Como voce disse que o objetivo é aprender depois de fazer usando DTO e as diversas maneiras que voce pensar com este modelo, de uma olhada em alguns posts aqui do GUJ, tais como:

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

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

E faca sem usar DTO.

Exemplificando sobre o código que tu postou.

[code]public class Aluno {

 // atributos
 private String nome;
 private String sobreNome;

 // métodos acessores
 public void setNome(String nome) {
   this.nome = nome;
 }
 public void setSobreNome(String sobreNome) {
   this.sobreNome = sobreNome;
 }
 //
 public void adicionaAluno() {
   Codigo que adiciona o Aluno.
 }

}[/code]

O objeto Aluno seria unico no teu dominio, nao teriamos AlunoBO e AlunoVO/DTO duplicando código. No metodo adicionaAluno pode ser feito em conjunto com o padrao command, delegando esse trabalho para classes auxiliares. Nos links que postei tem um exemplo do CV um pouquinho mais completo.

Completando a coleção de links:

O porque nao usar DTO.

http://www.martinfowler.com/bliki/AnemicDomainModel.html

Alternativas:

http://domaindrivendesign.org/

http://martinfowler.com/eaaCatalog/domainModel.html

Opa, o Phillip que me derrubar. :lol:
Tentei postar nos outros dois e só recebi “Este tópico se encontra bloqueado”.:shock:

La vai o que escrevi pro outro post.

Olá,

Thiago tu quer deixar nós louco? 3 tópicos sobre o mesmo assunto. Vá com calma, vamos discutir tudo em um só. :wink:

Ha um tempo atras eu tambem tinha esta mesma duvida, colocar o DAO diretamente ligado as classes de negocio. Depois de algumas leituras, artigos pra cá, livros pra lá. Fucando em código de outros projetos aqui outro lá. Cheguei a uma conclusao que nao seria o melhor a se fazer, mas ai tive um problema, como abstrair o DAO?

Bom pensando nisso eu fiz uma pequena arquitetura pra um sisteminha que construi, esta longe de ser uma otima arquitetura, mas gostei muito de trabalhar com ela, fora que foi muito facil colocar mais pessoas usando a mesma.

Ela ficou mais ou menos assim.

public interface Session { public void save(Bean bean) { } public void delete(Bean bean) { } public void update(Bean bean) { } public Bean get(Serializable id) { } public List find(String criteriaSearch) { } }

No meu Bean

public class Aluno implements Bean { //Atributos private transient Session session; private String nome; private String sobreNome; //Assecores public void setSession(Session session) { this.session = session; } public void setNome(String nome) { this.nome = nome; } .... public void addAluno(){ this.session.save(this); } }

Alguns detalhes, o atributo session da classe Aluno é adicionado via IoC entao nao é preciso se preocupar com ele. A unica classe que conhece o DAO é a implementacao de Session, o Bean nao quer nem saber onde estao sendo persistidos tudo, se é em banco, prevayler, ou arquivo texto. :smiley:
A implementacao de Session é criada quando eu inicio uma transacao, como eu tava usando WebWork isso era feito via interceptor e adicionado via IoC para quem precisa dela, como falei acima.
Alguns problemas, algo que eu nao tinha pensado e o Lipe me alertou, caso de transacoes com mais de uma acao (save, delete, etc).
Outra coisa que pode ser alterado é a forma das consultas, que hoje eu tava fazendo usando o padrao ValueListHandle, mas gostei de um exemplo que o CV colocou no post sobre Encapsulamento, ai to mudando isso.

]['s

esse tópico continua em

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

Olá GUJ’S

Primeiramente quero pedir desculpas pela bagunça que aprontei aqui no fórum criando três tópicos que abordavam sobre o mesmo assunto!
Foi sem querer mesmo, eu confundi fórum com grupo de discussão!

Minhas sinceras desculpas!

Quanto ao post do fabgp2001, quero dizer que achei muito boa a tua arquitetura! NO entanto, eu ainda nem sei o que é IoC. Mas viu, não precisa se preocupar não. Acho que a conversa já entrou em um nível além do meu conhecimento. Mas como a solução é ótima eu vou dar uma olhada nisso urgentemente. Vou ler os tópicos que vc indicou acima com calma e tentar identificar nestes posts as respostas para as minhas perguntas.

Acho que por hoje ja abusei da paciência dos GUJ’s!

Muito Obrigado!
Thiago

Eu até poderia tentar te explicar o que é, mas acho melhor tu ir na fonte.

http://www.javafree.com.br/home/modules.php?name=Content&pa=showpage&pid=4

]['s

esse tópico continua em

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

[size=18](postem lá, pessoal)[/size]

[quote=Thiago Senna]
Bom… eu coloquei tudo isso de patterns realmente para aprender, já que o mercado aprecia profissionais com conhecimento em patterns… [/quote]

Se o mercado apreciar mesmo profissionais com conhecimento em patterns, eu prefiro começar a vender cachorro-quente na Paulista.

Existe uma diferença muito grande entre “conhecer patterns” e “saber aplicar os patterns certos nos lugares certos”. :wink: