Caros, estou com um problema e não sei como aplicar o DDD aqui.
Por exemplo, eu possuo um Produto, e esse produto recebe uma categoria, e essa categoria pertence a um tipo.
Exemplo:
Produto: Caneta
Categoria: Material de escritório
Tipo: Mateiral
No meu sistema eu tenho uma tela para cadastar minhas categorias e cada categoria possui um tipo. Entao na minha classe Categoria eu possuo uma propriedade tipoCategoria que é um objeto da classe TipoCategoria.
O tipo da categoria serve apenas para identificar o tipo da categoria, na tabela não há nenhum dado a nao ser seu id e nome. Minha duvida é se é realmente necessário criar esse objeto para guardar o Numero e o Nome da categoria.(acho que nao eh)
Isso ta me causando alguns problemas na hora de retornar dados do banco, por exemplo, quando a Categoria já existe que eu executo um find(), ele retorna essa categoria com o objeto TipoCategoria normalmente. Pois quando ele retorna os dados, ele pega o numero do TipoCategoria na tabela e cria automaticaemnte o objeto. Mas quando o objeto nao foi persistido na tabela, ele nao possui um id do tipo de categoria, e na hora que eu tento salvar, consequentemente nao salva o id na tabela.
Acho que to me enrolando com besteira, mas pra mim ta complicar aplicar DDD e me abstrar do banco de dados. Alguns objetos eu considero VO(DDD), mas nao consigo nao guardar id deles para persistencia(isso é errado?)
Olá
Se um objeto é um VO, seu valor pode ser utilizado como chave primária do banco.
No seu caso, o tipo da categoria pode ser a chave da tabela.
…
Mas não se preocupe com banco agora. Desenvolva seu domínio primeiro e depois aplique a infra-estrutura nele. Utilize implementações dos seus Repositories que guardam os objetos em memória.
Mas eu acho que estou com um pouco de problema de interpretação. Tipo, se eu tiver um objeto TipoCategoria, eu só tenho guardado nele, o número dele(que no caso é o id dele na tabela) e o nome dele.
Quando eu vou salvar uma categoria, a unica coisa que me interessa do seu tipo, é o número e não o nome. Portanto eu acho que eu nao precisaria criar um objeto so para manipular o tipo da categoria, a categoria seria um dado como outro qualquer(o nome por exemplo).
Acho que você deve manter o objeto, mas como ele é um VO, você não precisa de um id porque o nome da categoria é tudo o que você precisa pra identificá-lo.
Se você mantiver o id, você poderá ter duas categorias iguais com ids diferentes.
Então ficaria algo assim:
[code]public class TipoCategoria {
private String tipoCategoria;
public TipoCategoria(String tipoCategoria) {
this.tipoCategoria = tipoCategoria;
}
// Escreva apenas um get, pois VOs são imutáveis
public String getTipoCategoria() {
return tipoCategoria;
}
}
// E na sua classe Produto…
public class Produto {
// …
private TipoCategoria tipoCategoria;
// …
}[/code]Abraços
Isso está certo. Antes de persistir a categoria vc tem que associar um tipo a ela (categoria.setTipo(tipo)).
Assim não vai dar problema. O seu problema aqui é a incosistência do objeto categoria antes de ser persistido.
O tipo é um campo obrigatorio , logo deve ser preenchido antes de persistir.
Não ha problema guardar chaves para os objetos. Isso tem a ver com a necessidade de mapear objetos em tabelas.
O que destingue um VO de uma Entidade não é o facto de ter ou não uma chave. O que destingue é a identidade.
TipoCategoria t1 = new TipoCategoria ("Material");
TipoCategoria t2 = new TipoCategoria ("Material");
persist(t1)
persist(t2)
Se TipoCategoria é um VO então t1 e t2 são a mesma coisa representada duas vezes.
Num banco tudo tem que ter um chave, mas nem tudo tem um ID (identificador)
Um VO teria uma chave que é igual ao seu proprio valor. Ou seja, a tabela TipoCategoria teria apenas um campo “nome” e ele seria a chave. Teria chave, mas não teria ID. Mas por motivos práticos vc não faz isso.
Se a categoria A e B pertencem ao mesmo tipo, elas apenas teria o “nome” do tipo como uma das suas colunas.
O problema é que vc quer poder mudar esse nome indepedentemente das associações que já fez. Por isso vc cria uma coluna numérica e a usa como chave. Dessa forma vc pode mudar o texto, sem mudar o conceito.
A diferença entre um VO e uma Entidade no dominio é que quando vc fizer equals() o VO irá comparar o nome.
Se fosse uma entidade ele ira comparar o ID. Se vc erradamente cadastrar dois tipos de categoria com o mesmo nome eles terão id diferentes. Ai , vc , erradamente cadastra duas categorias , cada uma usando um registro diferente do tipo. Mas quando vc izer o teste A.getTipo().equals(B.getTipo()) o resultado será true (os nomes são iguais). Embora os tipos sejam registros diferentes as categorias pertencem ao mesmo tipo.
Se tipoCategoria fosse uma entidade aquele mesmo teste daria false ( os id são diferentes)
Hmmm… entendi, muito boa as explicações… só mais uma duvida… se o que me interessa em TipoCategoria é o nome para que eu possa manter uma integridade, não há problema nenhum esse VO guardar o id da tabela apenas para quando eu for persistir a Categoria eu tenha a informação da chave que esse Tipo representa na tabela não é?
[editado]
Ah e outra coisa… se eu quiser garantir que o usuário não cadastre nenhum tipo de categoria que já existe(considerando que a chave é o nome), há algum padrão que me ajude a fazer isso em meu dominio?
E se o nome é a chave, quando eu for fazer o update na tabela, ao invés de eu fazer “… where id_tipo_categoria = 1” eu vou fazer “… where nm_tipo_categoria = ‘Materiais’” ?
[quote=brunoviana]Hmmm… entendi, muito boa as explicações… só mais uma duvida… se o que me interessa em TipoCategoria é o nome para que eu possa manter uma integridade, não há problema nenhum esse VO guardar o id da tabela apenas para quando eu for persistir a Categoria eu tenha a informação da chave que esse Tipo representa na tabela não é?
[/quote]
sim. Vc usa TipoCategoria.id como chave no banco e a tabela Categoria tem um campo que aponta essa chave
não sei se é um padrão, mas vc cria uma query com os campos que forma a chave de unicidade.
depois faz um query com esses campos "traga todos os X cujos campos são iguais a Y’.
Ai, se algum for retonado é porque está tentando criar duplicados. Em opção pode usar os recursos do banco para marcar o campo como único (o que eu não gosto de fazer…).
[quote]
E se o nome é a chave, quando eu for fazer o update na tabela, ao invés de eu fazer “… where id_tipo_categoria = 1” eu vou fazer “… where nm_tipo_categoria = ‘Materiais’” ?[/quote]
Se vc se refere a encontar o TipoCategoria que conrresponde a um certo nome, sim.
Se vc se refere a encontrar a Categoria de um certo tipo, não. Vc usa o id. “… where categoria.tipo = tipocategoria.id”