Objetos de valor versus entidade (Domain Driven Design)


90

Acabei de começar a ler DDD. Não consigo compreender completamente o conceito de objetos Entidade vs Valor. Alguém pode explicar os problemas (manutenção, desempenho, etc.) que um sistema pode enfrentar quando um objeto Valor é projetado como um objeto Entidade? Exemplo seria ótimo ...


2
Aqui eu escrevi uma lista completa (IMO) das diferenças entre os dois: enterprisecraftsmanship.com/2016/01/11/…
Vladimir

Respostas:


108

Reduzida à distinção essencial, a identidade importa para entidades, mas não importa para objetos de valor. Por exemplo, o Nome de alguém é um objeto de valor. Uma entidade Cliente pode ser composta de um Nome do cliente (objeto de valor), Lista <Order> OrderHistory (Lista de entidades) e talvez um Endereço padrão (normalmente um objeto de valor). A Entidade do Cliente teria um ID e cada pedido teria um ID, mas um Nome não deveria; geralmente, dentro do modelo de objeto de qualquer maneira, a identidade de um endereço provavelmente não importa.

Objetos de valor geralmente podem ser representados como objetos imutáveis; alterar uma propriedade de um objeto de valor essencialmente destrói o objeto antigo e cria um novo, porque você não está tão preocupado com a identidade quanto com o conteúdo. Adequadamente, o método de instância Equals em Name retornaria "true", desde que as propriedades do objeto sejam idênticas às propriedades de outra instância.

No entanto, alterar algum atributo de uma entidade como o Cliente não destrói o cliente; uma entidade Cliente é normalmente mutável. A identidade permanece a mesma (pelo menos depois que o objeto foi persistido).

Você provavelmente cria objetos de valor sem perceber; sempre que você estiver representando algum aspecto de uma Entidade ao criar uma classe de baixa granularidade, você terá um objeto de valor. Por exemplo, uma classe IPAddress, que tem algumas restrições em valores válidos, mas é composta de tipos de dados mais simples, seria um objeto de valor. Um EmailAddress pode ser uma string ou um objeto de valor com seu próprio conjunto de comportamentos.

É bem possível que mesmo os itens que possuem uma identidade em seu banco de dados não tenham uma identidade em seu modelo de objeto. Mas o caso mais simples é um composto de alguns atributos que fazem sentido juntos. Você provavelmente não deseja ter Customer.FirstName, Customer.LastName, Customer.MiddleInitial e Customer.Title quando você pode compô-los juntos como Customer.Name; eles provavelmente serão vários campos em seu banco de dados quando você pensar sobre persistência, mas seu modelo de objeto não se importa.


Onde os objetos mutáveis ​​não compartilhados se encaixam? Se em todo o universo existe apenas uma referência a um objeto, a identidade do objeto será irrelevante mesmo que seja mutável. A meu ver, uma coisa é uma entidade se existe uma referência que pode ser usada para observar um aspecto de estado que pode mudar sem que essa referência tenha sido usada para mudá-lo . Se uma coisa não se liga ao mundo exterior e é imutável ou apenas uma referência a ela existe em qualquer lugar do universo, então o cenário acima não pode ocorrer e é um valor.
supercat de

Algo como um int[1]pode ser um valor mutável não compartilhado, um valor imutável compartilhável (se nenhuma das coisas que contêm referências gravará nele) ou uma entidade (se houver duas ou mais referências, e uma delas pode ser usada para escrever valores que podem ser lidos com o outro). Infelizmente, não conheço nenhum suporte de linguagem em Java ou .NET para evitar que objetos de classe que encapsulam valores mutáveis ​​se transformem acidentalmente em entidades.
supercat de

@supercat, se você quer dizer sem suporte simples direto, eu concordaria, mas faço isso eliminando o acesso público aos construtores, usando apenas fábricas estáticas para criar novas instâncias e restringindo todo o acesso ao estado por meio de propriedades somente leitura (sem setters) .
Charles Bretana

36

Qualquer objeto definido coletivamente por todos os seus atributos é um objeto de valor. Se algum dos atributos mudar, você terá uma nova instância de um objeto de valor. É por isso que os objetos de valor são definidos como imutáveis.

Se o objeto não estiver totalmente definido por todos os seus atributos, haverá um subconjunto de atributos que constituem a identidade do objeto. Os atributos restantes podem ser alterados sem redefinir o objeto. Este tipo de objeto não pode ser definido como imutável.

Uma maneira mais simples de fazer a distinção é pensar em objetos de valor como dados estáticos que nunca serão alterados e entidades como dados que evoluem em seu aplicativo.


7

Tipos de valor:

  • Tipos de valor não existem por conta própria, depende dos tipos de entidade.
  • O objeto Value Type pertence a um Entity Type Object.
  • A vida útil de uma instância do tipo de valor é limitada pela vida útil da instância da entidade proprietária.
  • Três tipos de valor: Básico (tipos de dados primitivos), Composto (Endereço) e Coleção (Mapa, Lista, Matrizes)

Entidades:

  • Os tipos de entidade podem existir por conta própria (identidade)
  • Uma entidade tem seu próprio ciclo de vida. Pode existir independentemente de qualquer outra entidade.
  • Por exemplo: Pessoa, Organização, Faculdade, Celular, Casa etc. cada objeto tem sua própria identidade

Não relacionado ao DDD :(
HydTechie

6

Não sei se o seguinte está correto, mas eu diria que no caso de um objeto Address, queremos usá-lo como um Value Object em vez de uma Entity porque as alterações na entidade seriam refletidas em todos os objetos vinculados ( uma pessoa, por exemplo).

Veja este caso: você está morando em sua casa com outras pessoas. Se usássemos Entity para Address, eu argumentaria que haveria um Address exclusivo ao qual todos os objetos Person se vinculam. Se uma pessoa se mudar, você deseja atualizar o endereço dela. Se você atualizasse as propriedades da Entidade de Endereço, todas as pessoas teriam um endereço diferente. No caso de um Objeto de Valor, não poderíamos editar o Endereço (já que ele é imutável) e seríamos forçados a fornecer um novo Endereço para essa Pessoa.

Isso soa certo? Devo dizer que também fiquei / ainda estou confuso sobre essa diferença, depois de ler o livro DDD.

Indo um passo adiante, como isso seria modelado no banco de dados? Você teria todas as propriedades do objeto Address como colunas na tabela Person ou criaria uma tabela Address separada que também teria um identificador exclusivo? No último caso, as pessoas que moram na mesma casa teriam cada uma uma instância diferente de um objeto Endereço, mas esses objetos seriam os mesmos, exceto por sua propriedade de ID.


1
"Considere este caso: você está morando em sua casa com outras pessoas. Se usássemos Entidade para Endereço, eu argumentaria que haveria um Endereço exclusivo ao qual todos os objetos Pessoa se vinculam". Acho que cada uma dessas pessoas tem sua própria instância de Address, mas elas são iguais (é como se cada uma delas pudesse ter uma nota de 5 dólares, mas isso não significa que é a mesma nota)
Prokurors

"mas isso não significa que é a mesma nota" - acho que isso depende de se atribuir ou não propriedades adicionais à nota (por exemplo, data de emissão, localização física no espaço, etc.); caso contrário, eles seriam os mesmos. E eu acho que é o mesmo para o software: o endereço é o mesmo ou não, dependendo das propriedades que precisamos / queremos considerar.
adrhc 01 de

4

endereço pode ser entidade ou objeto de valor que depende do processo de negócios. o objeto de endereço pode ser uma entidade no aplicativo de serviço de correio, mas o endereço pode ser um objeto de valor em algum outro aplicativo. em questões de identidade de aplicativo de correio para objeto de endereço


2

Eu perguntei sobre isso em outro tópico e acho que ainda estou confuso. Posso estar confundindo considerações de desempenho com modelagem de dados. Em nosso aplicativo de Catalogação, um cliente não muda até que precise. Isso parece idiota - mas as 'leituras' de dados do cliente superam em muito as 'gravações' e, uma vez que muitas solicitações da web estão todas atingindo o 'conjunto ativo' de objetos, não quero continuar carregando clientes repetidamente. Então, eu estava seguindo por uma estrada imutável para o objeto Cliente - carregue-o, armazene-o em cache e forneça o mesmo para 99% das solicitações (multithread) que desejam ver o Cliente. Então, quando um cliente muda algo, peça a um 'editor' para fazer um novo cliente e invalidar o antigo.

Minha preocupação é se muitos tópicos veem o mesmo objeto de cliente e ele é mutável, então, quando um tópico começa a mudar, o caos ocorre nos outros.

Meus problemas agora são: 1) isso é razoável e 2) a melhor forma de fazer isso sem duplicar muito código sobre as propriedades.


1

3 distinção entre EntitieseValue Objects

  • Identificador vs igualdade estrutural: as entidades têm identificador, as entidades são iguais se tiverem o mesmo identificador. Objetos de valor além da mão têm igualdade estrutural, consideramos dois objetos de valor iguais quando todos os campos são iguais. Objetos de valor não podem ter identificador.

  • Mutabilidade vs imutabilidade: Objetos de valor são estruturas de dados imutáveis, enquanto as entidades mudam durante seu tempo de vida.

  • Vida útil: Objetos de valor devem pertencer a entidades


1

Em uma frase muito simples, posso dizer, temos três tipos de igualdade:

  • Igualdade de identificador : uma classe tem um campo de id e dois objetos são comparados com seu valor de campo de id.
  • Igualdade de referência : se uma referência a dois objetos tem o mesmo endereço na memória.
  • Igualdade estrutural : dois objetos são iguais se todos os membros deles forem correspondidos.

Igualdade de identificador refere-se apenas a Entidade e igualdade estrutural refere-se apenas a Objeto de Valor. Na verdade, os Objetos de Valor não têm id e podemos usá-los de maneira intercambiável. também os objetos de valor devem ser imutáveis ​​e as entidades podem ser mutáveis ​​e os objetos de valor não terão tabela nay no banco de dados.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.