Informações de endereço devem ficar juntas ou separadas do modelo a qual elas se referem?

Eu estava discutindo com um amigo sobre um aspecto de uma aplicação que estamos desenvolvendo, e então entramos num embate. Esta é a situação: a aplicação possui lojas, e uma das informações que as lojas possuem é o endereço. Eu sugeri que as lojas possuam um modelo/tabela para a loja, sendo que esse modelo/tabela se relaciona com um outro modelo/tabela para o endereço. Esse modelo/tabela para o endereço, por sua vez, se relaciona com alguns outros modelos/tabelas, como um modelo/tabela para as cidades e para os estados. Uma das vantagens que eu vejo nessa abordagem é que pelo fato do endereço ter vida própria, ele pode se relacionar com as lojas, como também pode se relacionar com outras entidades da aplicação.

Já este meu amigo, sugeriu colocar o endereço da loja no modelo/tabela da loja, ou seja, tudo ficaria concentrado no mesmo modelo/tabela. Eu achei essa opção ruim, já que ao meu ver é anêmica, uma vez que a o model da loja estaria representando muitos conceitos simultaneamente, resultando em uma classe com diversas métodos e validações não muito relacionados, além de testes bem gordos. Ao argumentar contra a idéia, ele disse que essa é a melhor opção por ser mais simples e performática. De fato é a mais simples, ou melhor, é a mais simplória. Já em relação a performance ela realmente é ligeiramente melhor, uma vez que evita consultas a outras tabelas, o que é amenizado pelo lazy loading no caso da minha sugestão.

Enfim, eu acredito que estou certo quando ao meu ponto de vista. Acho que é incabível colocar a informação do endereço no mesmo model/tabela que as informações mais gerais da loja. De início até achei que ele estava sugerindo que o model/tabela dos endereços centralizasse as informações dos endereços, e que esse se relacionasse com o modelo das lojas, o que eu acho mais razoável, embora ainda prefira a opção de ter um model/tabela pra cada informação.

Acontece que esse meu amigo é um bom desenvoveldor, o que me fez ficar na dúvida se não sou eu que estou sendo formal demais. Sendo assim, gostaria da opinião dos demais usuários do GUJ.

Não tem um errado nessa história, são 2 modos de se fazer a mesma coisa. Tem que ver o melhor pra sua situação.

Eu particularmente iria também preferir separar o endereço da loja. Assim, se outra parte do sistema usar os endereços, as cidades e os estados já tem tudo ali pronto.

Por se tratar de endereço de uma “Loja” eu também ficaria com a segunda opção. Você não vai reaproveitar essa tabela/modelo de endereços, vai por mim. Se tiver que fazer isso é melhor usar um modelo separado com dados do correio ou desse tipo. É melhor colocar na tabela da loja para evitar vários acessos no banco de dados e até a criação de classes a mais para tratar uma coisa que será sempre da mesma maneira.
Se fosse o endereço do cliente por exemplo ai faria mais sentido usar a tal tabela/ modelo dos correios. Não consigo ver onde você aproveitaria esses dados do endereço se separa-los das lojas. De qualquer forma para te ajudar basta fazer uma pergunta fácil fácil:

O Endereço pode existir no sistema sem que haja uma loja associada a ele?
Sim - faça o modelo separado e quando for cadastrar uma loja obrigue o usuário a escolher/pesquisar um endereço existente.
Não - faça junto com a loja.

Lembre-se que uma loja é única e possui apenas 1 endereço, mesmo que seja na mesma rua ela tera um número diferente.

[quote=mvargens]Por se tratar de endereço de uma “Loja” eu também ficaria com a segunda opção. Você não vai reaproveitar essa tabela/modelo de endereços, vai por mim. Se tiver que fazer isso é melhor usar um modelo separado com dados do correio ou desse tipo. É melhor colocar na tabela da loja para evitar vários acessos no banco de dados e até a criação de classes a mais para tratar uma coisa que será sempre da mesma maneira.
Se fosse o endereço do cliente por exemplo ai faria mais sentido usar a tal tabela/ modelo dos correios. Não consigo ver onde você aproveitaria esses dados do endereço se separa-los das lojas. De qualquer forma para te ajudar basta fazer uma pergunta fácil fácil:

O Endereço pode existir no sistema sem que haja uma loja associada a ele?
Sim - faça o modelo separado e quando for cadastrar uma loja obrigue o usuário a escolher/pesquisar um endereço existente.
Não - faça junto com a loja.

Lembre-se que uma loja é única e possui apenas 1 endereço, mesmo que seja na mesma rua ela tera um número diferente.[/quote]
Parte da informação do endereço será reaproveitada sim, no caso o estado, uma vez que os usuários terão essa informação também, e talvez possuam endereço completo no futuro.

Outro motivo pelo qual eu quero colocar em modelos/tabelas separadas é pra poder criar um script que carregue todas os estados e cidades do Brasil, além de relacionar cada cidade com seu respectivo estado. Dessa forma, a seleção de ambos se dá através de um combo box, onde primeiro seleciona-se o estado, e em seguida o combo box das cidades é preenchido. Tendo isto em vista, fica ainda mais difícil e, na minha opinião, estranho, usar a tabela de lojas pra inserir os estados e cidades do Brasil pra popular os combo box mencionados.

Realmente fica estranho usar a tabela de loja para carregar 1 combo que poderia até ser fixo. Mais eu ainda acho mais estranho criar um modelo de dados complexo (vide o modelo dos correios) por causa de um combo fixo.
Acho que sua intenção é boa, mas um modelo de endereços realmente funcional é bem complexo. Lembre-se que vai ter que quebrar e associar por Cep, endereço, complemento, numero, bairro, cidade, estado.
Deixar o usuário digitar o endereço é a pior coisa que você pode fazer em um modelo assim. Ou você tem tudo pronto ou é melhor nem fazer. Por isso recomendei o esquema dos correios.
Você deve ter um prazo para entregar isso ai. Pense nas classes e testes que terá que fazer para manter esse modelo. Se vai fazer meia boca é melhor fazer do jeito que seu amigo propôs.
Agora se está convencido que vai reaproveitar todo o modelo de endereço em outra parte do sistema não faz sentido não fazer separado.

[quote=mvargens]Realmente fica estranho usar a tabela de loja para carregar 1 combo que poderia até ser fixo. Mais eu ainda acho mais estranho criar um modelo de dados complexo (vide o modelo dos correios) por causa de um combo fixo.
Acho que sua intenção é boa, mas um modelo de endereços realmente funcional é bem complexo. Lembre-se que vai ter que quebrar e associar por Cep, endereço, complemento, numero, bairro, cidade, estado.
Deixar o usuário digitar o endereço é a pior coisa que você pode fazer em um modelo assim. Ou você tem tudo pronto ou é melhor nem fazer. Por isso recomendei o esquema dos correios.
Você deve ter um prazo para entregar isso ai. Pense nas classes e testes que terá que fazer para manter esse modelo. Se vai fazer meia boca é melhor fazer do jeito que seu amigo propôs.
Agora se está convencido que vai reaproveitar todo o modelo de endereço em outra parte do sistema não faz sentido não fazer separado.[/quote]
Na verdade eu já fiz algo parecido em outra ocasião. Nessa outra aplicação, o usuário informava o CEP, a aplicação buscava o logradouro, bairro, estado e cidade baseados no CEP informado, e então o usuário só precisava preencher o número e, opcionalmente, um complemento. Além disso, todas as associações eram feitas, além de garantir que o mesmo endereço, assim como os seus componentes individuais, nunca seriam salvos duas vezes (não faz sentido, por exemplo, salvar duas vezes a cidade “Rio de Janeiro” na tabela de cidades). Enfim, era algo mais ou menos assim:

Ótimo, você conhece a solução e sabe quanto tempo leva. O problema é apenas saber se vale o esforço sim ou não. Eu acho que não vale, mas sem duvida nenhuma é melhor fazer assim até porque quem vai cadastrar a loja só precisa digitar o cep, número e complemento. Mas lembre-se, você tem prazo para entregar isso funcionando do jeito que pediram.

[quote=elomarns]

Já este meu amigo, sugeriu colocar o endereço da loja no modelo/tabela da loja, ou seja, tudo ficaria concentrado no mesmo modelo/tabela. Eu achei essa opção ruim, já que ao meu ver é anêmica, uma vez que a o model da loja estaria representando muitos conceitos simultaneamente, resultando em uma classe com diversas métodos e validações não muito relacionados, além de testes bem gordos. Ao argumentar contra a idéia, ele disse que essa é a melhor opção por ser mais simples e performática. De fato é a mais simples, ou melhor, é a mais simplória. Já em relação a performance ela realmente é ligeiramente melhor, uma vez que evita consultas a outras tabelas, o que é amenizado pelo lazy loading no caso da minha sugestão.

Enfim, eu acredito que estou certo quando ao meu ponto de vista. Acho que é incabível colocar a informação do endereço no mesmo model/tabela que as informações mais gerais da loja.
… [/quote]

Independente de como você fará isso no seu banco de dados, isso não precisa refletir o domínio da sua aplicação. As tuas classes não precisam se espelhar nas tabelas. Você pode ter uma tabela Loja com campos de Endereco, porém no sistema você tem uma classe Loja que possui um Endereco. Aliás, você nem deve armazenar essas ‘validações’ de Endereco na classe que representa a tua Loja.

Se você tiver, leia no DDD a respeito de Value Objects e Entities. Me parece que a sua dúvida pode ser em relação a isso (como você define um endereço, já que ele pode ser visto tanto como um Value Object como uma Entity).

Falou.