[quote=alias][quote=sergiotaborda][quote=alias]Olá amigos do fórum,
Gostaria de uma ajuda/sugestões com a modelagem de um objeto aqui. Não estou satisfeito com a forma que implementei.
Tenho um objeto Endereco, que possue os atributos cep, logradouro, cidade, etc.
Tenho um objeto Telefone, que possue os atributos ddd e numero.
Por fim, tenho um objeto Usuario que tem um Endereco e um Telefone.
Minha idéia era que o Usuario atuasse como um Aggregate, encapsulando um endereco e um telefone, e, aplicando a lei de Demeter, fizesse todos os acessos pertinentes a esses objetos. O resultado final foi algo proximo disso:
[/quote]
Vc está confundindo o que significa “Agregate”.
Agregado é um objeto que é composto de outros e que cuja vida desses outros está relacionada à do agregado. O exemplo classico é Pedido-Itens.
Endereçoe e Telefone são propriedades do usuário. Só isso. É uma simples composição. Não ha controle de ciclo de vida.
Isso que vc tentou de colocar as cmadas no usuário é simplesmente errado.
Primeiro vc cria o objeto endeeço e telefone separadamente.Depois dá um usuário.setEndereco e usuario.setTelefone. Simples. Como se fose uma string ou uma data.
Note que a relação pessoa -> endereço não é 1 para 1. É uma para muitos. O mesmo com telefone. E vc precisa de um qualificador. Por exemplo, edereço de correspondencia, endereço de cobrança, endereço de entrega. Telefone celular, Telefone comercial, telefone de emergencia, telefone de cada , etc… Esta relação mais real, também lhe indica que realmente o usuário não é um agregado desses objetos. Ele é relacionado a esses objetos, mas não é dono deles.
[/quote]
Oi sergiotaborda, obrigado pelas sua resposta.
Talvez não tenha explicado bem o cenário, pois no meu dominio a situaçao é justamente essa que você citou do agregado. Eles pertencem ao Usuario, efetivamente. Não há sentido no meu modelo ter um Telefone que nao pertença a um usuário, e nem um Endereço que não pertença a um usuário. Crio-os em conjunto, e removo-os em conjunto também (e também o usuário de fato só tem UM telefone e um endereço, entendo o que disse mas no meu domínio não faz sentido ter qualificadores pra esses caras).
Devido a esses detalhes que quis fazer o Usuario encapsular esses objetos, e não um “setEndereco” ou “setTelefone”. Dado esse cenário você ainda acha melhor fazer os setters?
Obrigado!
[/quote]
Você está incorrendo um erro que é muito comum, está confundinco "Ser composto de " com “Pertencer a”.
Em OO estes dois conceitos são implementados da mesma forma, com um private do tipo em questão.
quando vc diz que Endereço pertence a Usuario , vc quer dizer que Usuario tem um private do tipo Endereço.
Só que “Pertencer A” é uma relação mais poderosa que “Ser composto de”. Por exemplo, listas carrega vários objetos. Elas são compostas de objetos, mas os objetos não pertencem à lista. Ou seja, não é a Lista que sabe como, quando e porque um objeto dentro dela é criado. Não. É apenas um arranjo de objetos. Assim como um array ou qualquer tipo de estrutura dessas. Itens e Pedido é outra coisa. Os itens pertencem ao Produto. E isto não é porque o Pedido tem uma Lista de Itens é porque realmente não é possivel ter um item fora do pedido. Se vc tiver o objeto de item, a primeira coisa que vai querer saber é “Qual é o pedido onde este item está”. Mas o item diz respeito a um produto. O Produto não pertence ao Item. Então em java o produto é um private do item, e o item está em uma lista que é private do pedido, mas o item pertence ao pedido, o produto não pertece ao item.
Deu para entender ?
Da mesma forma, o private no objeto vai se trasnformar num campo em alguma tabela. A mesma coisa. O fato da tabela ter uma referencia à outra, não cria um vinculo “pertence a”, apenas cria uma relação. Nisso o banco é mais burro ainda que OO pois ele não destingue entre “é composto” ou “pertence a” ou “é relacionado com”.
Portanto tenha cuidado. quando vc diz que o Endereço só existe no Usuário isso não é verdade. Vc pode pesquisar assim “me dâs todos os endereços de todos os usuários do sistema”. Quando a lista de endereços retornar é irrelevante qual o usuario a que está anexado. Isso prova que o Endereço não pertence ao usuario. Ele está composto no usuario. Coisas que pertencem ao usuário são o nome, a senha, o email , coisas que são realmente dele e de mais ninguem.
Em UML vc representa a linha de Usuario para Endereço com um losanglo branco, não o preto. Mas pedido e item vc representa com o preto. A diferença é que o “new” de Endereço é dado no sistema, não no objeto usuário. E o “new” de pedido é dado no pedido, não no sistema.
Em resumo, duplicar todos os get/set da entidade X na entidade Y é errado. Seja qual for a relação entre elas. SE ha composição, então Y é criado pelo sistema e passado a X num set (ou no construtor). Se é algo mais complicado, outras construções podem ser necessáriaos (como o uso do padrão Builder).
O que eu queria que ficasse claro é que , não é porque ha um private que isso signfiica que ha uma relação “Pertence A”. As relações de composição ou “pertence a” vêm do mundo real. O modelo pode escolher ignorar o mundo real, mas normalmente isso é arranjar problemas porque quando vc for usar os objetos as pessoas pensam em termos do mundo real. Tipo, o outro programador que for usar API está à espera que existe uma classe Endereço se o sistema lida com endereços. Por quê ? Porque endereço é um conceito em si mesmo. O sistema pode pegar esse endereço e mandar para uma API dos correios para postagem ou para uma API de mapas para localização, para uma API de routing de entregas, etc… O endereço vive sozinho no mundo, então o programador espera um objeto sozinho. Se vc obrigar o cara a usar um objeto Usuario , com os get/set de endereço a primeira coisa que o programador vai fazer é criar uma interface Endereço e fazer usuario impleentá-la. fica uma merda, mas ele vai poder usar apenas o lhe interessa. Ou o cara vai fazer um de-para de usuario para endereço. Não tente a sorte e dê ao programador o que ele espera. E ele sempre espera o que o mundo real tem ( a isso se chama Principio da Minima Surpresa). Não surpreenda os seus colegas com designs loucos, apresente o que eles esperam.