Modelagem, Hibernate de BD... como é?

15 respostas
S

[color=“blue”]Oi pessoal, estou desenvolvendo um sistema so que estou em dúvida sobre uma parte do problema mais conceitual… vou utilizar BD(ainda não sei qual) e usar o hibernate pra mapear objeto/relacional. :roll:

Modelando o bd com UML estou vendo que não preciso criar, por exemplo, o metódo inserir para cada classe(tabela)… eu poderia criar uma classe que represente simplesmente o BD pra manipular e ter todos os metódos como inserção, editar, apagar, etc ? Porque se eu colocar isso em cada classe eu vou ter uma redundancia desnecessária não é ?! No caso então, as classes teriam so os atributos… que no modelo relacional(BD) seriam os campos… :?:

Sei que essa questão é muito simples… mais fazer o que, tenho que perguntar pra ter certeza… :oops:

Valeu pessoal !!!
SkyBlue[/color]

15 Respostas

cv1

Voooolta, volta volta volta! :D

Se voce esta usando o Hibernate (ou outro mapeador Objeto-Relacional), vc nao tem que pensar nas tabelas, vc tem que pensar nos objetos. Entao esqueca que existe um banco de dados enquanto vc estiver fazendo a modelagem, e deixe as coisas o mais OO possivel ;)

Resumo da opera, aqui vai um trechinho do que passou pela cabeca esquizofrenica do cv (nao a minha, a do cv!):

- Ei, preciso de um objeto pra representar clientes.
- Tah, q q o cliente tem?
- Nome, endereco, telefone e e-mail.
- E o que a gente pode pedir pra ele fazer?
- Bom, ele consegue se logar, deslogar, adiciona comentarios aos produtos, compra coisas, e pode enviar comentarios direto pra gente.
- Legal. Dah uma olhada nisso aqui entao e ve se eh o que vc quer:

public class Cliente implements java.io.Serializable {
  private boolean logado = false;
  private String nome = "";
  private String endereco = "";
  private String telefone = "";
  private String email = "";

  public void logar() {
    ...
  }

  public void deslogar() {
    ...
  }

  public void comentarProduto(String comentario, Produto produto) {
    ...
  }

  public void comprarProduto(Produto produto) {
    ...
  }

  public void comentar(String comentario) {
    ...
  }
  
  // getters e setters pros atributos
}

- Show! Agora eh soh fazer um JUnit pra ter sempre como acompanhar esse codigo aqui. Vou usar o wizard babinha do Eclipse pra isso, segura um pouco.
- Tah...
- Mas, erhm... como eu salvo um objeto desses? Se a aplicacao cair eu fico sem os dados...
- Ah eh... Prevayler ou Hibernate?
- Hibernate! O chefe nao gosta de Prevayler.
- Tah. Pega o XDoclet, monta um script Ant que faz a papagaiada toda com o HibernateDoclet e me chama. Vou tomar um cafe...
- Beleza.

(algum tempo depois...)

- E ai?
- Pronto! So tem um problema, quem cuida de salvar e pegar esses clientes?
- E se a gente fizesse um DAO?
- DAO? Credo, c tah fora de moda mesmo. Nao eh mais DAO que se chama o pattern. Eh Table Data Gateway. Burro.
- Ah eh. Bom, e se a gente fizesse um TDG?
- Boa. Vamo lah:

public class ClientesTDG {

  public Cliente[] pegaCliente() {
    ...
  }

  public Cliente[] pegaCliente(String nome) {
    ...
  }

  public boolean apagaCliente(Cliente cliente) {
    ...
  }

  public boolean alteraCliente(Cliente cliente) {
    ...
  }

}

- Perae. Nao ficou faltando alguma coisa, nao?
- Hmm... verdade. As Exceptions! Vou adicionar os throws aqui.
- Boa! Acho que eh isso, nao?
- Nao sei ueh, pergunta pro codigo, nao pra mim! Roda o JUnit. :D

PS: Foi mal. Esse post tah ridiculo. Sushi me deixa criativo demais, e botaram alguma coisa naquele shoyu.

S

[color=“blue”]Oi pessoal !!!

Seguinte CV, acho que a discussão é bem mais teórica agora…

Ótimo, você ta pensando em uma simples classe Clientes, concordo que devo esquecer o banco de dados… mas quando pensamos que na maioria das vezes temos mais classes para poder manipular e armazenar esses dados, temos um problema.

O que essas classes tem em comum ? os mesmos métodos de manipulação… não sei mais talvez aí entre o AOP, que é orientado à aspectos(ou caracteristicas).

Se tenho as mesmas operações(métodos) em várias classes porque não junta-los em uma só classe para que possam ser utilizados para operar nas classes necessárias ?! Evitaria a redundancia de métodos…

Vamos a um exemplo prático… eu tenho a classe Clientes e Fornecedores, porque não posso pegar os métodos como inserir, editar e apagar, que eles tem em comum e colocar em outra classe ?

Valeu CV, pessoal !!!
SkyBlue[/color]

cv1

Calma :smiley:

AOP eh uma boa pedida pra esse tipo de coisa, mas da pra resolver direitinho sem “apelar” pra outros paradigmas… vamos dar uma olhada nessas solucoes primeiro :slight_smile:

De uma lida melhor sobre Table Data Gateways (ou Abstract DAOs). Voce ainda pode reusar bastante codigo soh com a boa e velha heranca e polimorfismo :wink:

Continuando num exemplo pratico, entao… voce veria que tem codigo duplicado e refatoraria. Simples, pratico, rapido :wink:

S

[color=“blue”]Vai me desculpar CV mais acho que você ta me enrolando… falou, falou e não falou nada. :roll:

Qual é o problema com a minha idéia ? tem alguma contradição, erro ou é uma má prática ?! Tô tentando fazer da maneira mais simples, prática e lógica possível… 8)

Não entendi esse negócio de refatorar… como refatorar com essa redundancia ?!

Valeu pessoal !!!
SkyBlue[/color]

brlima

SkyBlu,

Acho que entendi o que vc quer. Seria como ter um método:

class banco{ public void inserir( Object classe ){} public void deletar( Object classe ){} public void atualizar( Object classe ){} }

onde vc passaria o seu Cliente ou seu Fornecedor ou mesmo seu Produto como parametro o o método saberia o que fazer, serto ???

Se for isso, existem n maneiras de fazer. Voce pode criar um arraylist dos campos que vc tem em cada classe, e no metodo inserir, vc leria os campos, montaria sua SQL de intert com os valores de cada campo, etc…

Espero que seja isso… Abraços…

cv1

Whoops, ateh que enfim me pegaram! :oops:

Eu venho fazendo isso desde q eu entrei no GUJ (po, quase um ano!) e vc foi o primeiro a perceber… droga, vou ter q abandonar o forum… perdeu a graca agora :smiley:

Nao tem problema nenhum com a sua ideia de ja sair fazendo um TDG maneiro que sabe lidar com tudo quanto eh tabela… claro, vao sempre existir uns casos onde eh melhor fazer algo especifico (dah uma olhada no HibernateDAO do GUJ2, a gente caiu nesse caso).

O ponto que eu tava querendo ilustrar eh que se vc comeca com o design mais simples possivel, e tenta manter a coisa o mais simples possivel, melhorando sempre o codigo e deixando tudo limpinho e consistente, fica uma baba trabalhar :wink:

Mas, recapitulando a historia do AOP: se vc quiser aproveitar pra dar uma olhada, vale a pena, mas ainda assim, esse eh um problema que pode ser resolvido meramente com patterns bem aplicados - voce pode usar AOP, mas seria “apelar”, usar uma retro-escavadeira pra cortar a grama :smiley:

Tem uma regrinha no XP (Extreme Programming) que eu gosto bastante: Once And Only Once: desenvolva determinada funcionalidade do sistema uma vez, e apenas uma vez. Em geral, numa linguagem OO eh possivel fazer isso facilmente, e vc vai acabar notando que existem mil maneiras de se fazer isso no caso especifico dos TDGs. O ponto todo da discussao aqui foi nao tentar se apressar e fazer um treco generico e reusavel logo de cara, pq isso, em geral, torna seu sistema mais complexo (quanto mais generico, mais partes moveis no sistema tem que estar em sincronia pra coisa toda funcionar)

S

[color=“blue”]Oi pessoal !!! Estive pensando em qual seria a melhor solução para este caso das classes do banco de dados e acho que a maneira mais simples e prática é mesmo a que o brlima citou… :idea:

Vou criar uma classe BD, nela eu coloco os métodos de manipulação de dados e as classes(tabelas) do bd herdam estes métodos… bem simples mesmo, acho que não vou ter nenhum problema e com isso vou evitar a redundacia de código desnecessária. 8)

CV também ajudou bastante, infelismente eu não tenho muito tempo pra estudar AOP, ainda não quero partir pra essa área sem antes ter mais conhecimento e prática em OO mais sem dúvida AOP também é muito interessante. :wink:

Entendi o que você quizer mencionando o XP mais acho que essa parte é muito simples e não existe problema em ser genérica… o meu sistema não é assim de grande complexidade no geral. :roll:

Valeu pessoal !!!
SkyBlue[/color]

urubatan

seguite, vc esqueceu das pesquisas que normalmente é esta classe DAO (ou TDG) que vai fazer, então para não repetir os inserts e deletes, vc tem duas opções (que me ocorreram agora, com certeza deve ter muito mais :-) )

public abstract class AbstractDAO{
 public void insert(Object o){...}
 public void delete(Object o){...}
 public void update(Object o){...}
}

public class ClienteDao extends AbstractDAO{
 public Collection buscaClientePorNome(String nome){...}
}

ou então, utilizar uma Criteria API do hibernate ou algo do genero, só que ai, os DAOs/TDGs não vão mais encapsular toda a lógica de acesso a dados, o resto da aplicação vai ter de saber qual tecnologia tu ta usando (Hibernate por exemplo) para poder criar as consultas, utilizando a API de criterios deles, e se um dia tu resolver mudar para JDO, OJB ou Entity Beans por exemplo, você vai ter que mudar toda a sua aplicação, mas se o DAO fizer internamente todas as pesquisas, vc muda de tecnologia de armazenamento alterando apenas os DAOs.

S

[color=“blue”]Oi pessoal !!! É mesmo, eu tava esquecendo desse detalhe tão importante urubatan… as consultas, ou pesquisas… mais eu não entendi exatamente o que você quiz dizer em relação aquele código…

Como eu faria esse tipo de consulta com o código que você passou ? Realmente seria melhor eu encapsular a lógica de acesso aos dados… e como eu faria para o DAO fazer internamente essas pesquisas pra mim ? basta dar um exemplo simplesinho… :?:

Acho que não teria necessidade de mudar, mesmo que futuramente, do Hibernate para outro mapeador mas fiquei interessado em saber como fazer isso que você falou… mais isso aí também tem a desvantagem de - se eu uso o Hibernate, não vou usar os recursos(API) que ele me proporciona ? :roll:

Valeu pessoal !!!
SkyBlue[/color]

urubatan

por exemplo, caso você mantenha toda a tecnologia de acesso a dados “presa” dentro do DAO, você faria uma busca da seguinte maneira.

usuarioDAO.buscaUsuario(nome, endereço,cpf);

se você deixar isto “vazar” para o resto da aplicação e por acaso esteja utilizando hibernate:

List cats = dao.createCriteria(Usuario.class) .add( Expression.like("nome", "Fritz%") ) .add( Expression.between("weight", minWeight, maxWeight) ) .list();

sendo que para isto, você fica dependente em toda a sua aplicação de classes do hibernate, como, por exemplo:
Expression, pode ficar também de Criteria, …

S

[color=“blue”]Oi pessoal !!! urubatan então você esta sugerindo que eu crie outra camada que chame os métodos do Hibernate para executar as consultas ?

Essa busca por exemplo… de qualquer maneira eu vou ter que utilizar o hibernate passando parâmetros para a consulta que o Hibernate irá fazer… é isso ?

Se for, não entendi a vantagem… de qualquer jeito teria que alterar as consultas se eu resolver mudar de tecnologia.

Valeu pessoal !!!
SkyBlue[/color]

Daniel_Quirino_Olive

A vantagem é que você não vai misturar a lógica de acesso a dados com outras lógicas do seu sistema (apresentação, controle, …). Desta forma, a manutenção do seu programa fica mais facilitada, além de você poder, quem sabe, reutilizar seus objetos para outros projetos.
Dica: leia a seção sobre Data Access Object (vulgo DAO, rebatizado com um nome feio que o Clos vive repetindo) no J2EE Design Patterns. http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html

Douglas

CV, vc que manja, que tal um tutorial pro GUJ com um tema como: “Implementando persistencia com Eclipse/Ant/XDoclet/Hibernate”
podia mesmo ser umas classes babinhas como essa que vc citou só pra dar uma ideia pra nós (principiantes). Ia ser demais!!! :smiley: :smiley: :smiley:

Abraco forte a todos do GUJ

cv1

Pode ate ser, mas inventar dialogo se torna bem cansativo depois de um tempo… alguem quer ser a cobaia pro artigo? :smiley:

Daniel_Quirino_Olive

“Douglas”:
CV, vc que manja, que tal um tutorial pro GUJ com um tema como: “Implementando persistencia com Eclipse/Ant/XDoclet/Hibernate”
podia mesmo ser umas classes babinhas como essa que vc citou só pra dar uma ideia pra nós (principiantes). Ia ser demais!!! :smiley: :smiley: :smiley:

Abraco forte a todos do GUJ

Bahhh, qual é, povo? Exercitem um pouquinho o português e ambos os lados do cérebro, e façam vocês mesmo os artigos. Estudem os temas e compilem o conhecimento que vocês obtiveram em um artigo. Acreditem: vocês aprendem muito mais escrevendo do que apenas lendo :wink:

p.s.: os autores do dois melhores artigos concorrem a um vale-livro cada, oferecido pela Tempo Real. Eis mais um bom motivo para vocês começarem a usar o teclado para outra coisa que não codificar e jogar Counter Strike.

Criado 19 de janeiro de 2004
Ultima resposta 31 de jan. de 2004
Respostas 15
Participantes 6