Ценность против объектов сущностей (доменный дизайн)


92

Я только начал читать DDD. Я не могу полностью понять концепцию объектов Entity vs Value. Может кто-нибудь объяснить проблемы (ремонтопригодность, производительность и т. Д.), С которыми может столкнуться система, когда объект Value разработан как объект Entity? Пример был бы отличным ...


3
Здесь я написал полный (IMO) список различий между ними: enterprisecraftsmanship.com/2016/01/11/…
Владимир

Ответы:


109

Если сводится к существенному различию, идентичность имеет значение для сущностей, но не имеет значения для объектов-значений. Например, чье-то Имя - это объект-значение. Сущность Customer может состоять из имени клиента (объект значения), List <Order> OrderHistory (список сущностей) и, возможно, адреса по умолчанию (обычно объекта значения). Сущность клиента будет иметь идентификатор, и каждый заказ будет иметь идентификатор, но имя не должно; в любом случае в объектной модели идентичность адреса, вероятно, не имеет значения.

Объекты значений обычно могут быть представлены как неизменяемые объекты; изменение одного свойства объекта значения по существу разрушает старый объект и создает новый, потому что вас не так заботит идентичность, как контент. Правильно, метод экземпляра Equals для Name будет возвращать «true», если свойства объекта идентичны свойствам другого экземпляра.

Однако изменение некоторого атрибута объекта, такого как Customer, не уничтожает клиента; Сущность Customer обычно изменяема. Идентификатор остается прежним (по крайней мере, после сохранения объекта).

Вы, вероятно, создаете объекты-ценности, даже не осознавая этого; Каждый раз, когда вы представляете какой-либо аспект сущности, создавая детальный класс, у вас есть объект значения. Например, класс IPAddress, который имеет некоторые ограничения на допустимые значения, но состоит из более простых типов данных, будет объектом значения. EmailAddress может быть строкой или объектом значения со своим собственным набором поведения.

Вполне возможно, что даже элементы, у которых есть идентификация в вашей базе данных, не имеют идентичности в вашей объектной модели. Но самый простой случай - это сочетание некоторых атрибутов, которые имеют смысл вместе. Вы, вероятно, не захотите иметь Customer.FirstName, Customer.LastName, Customer.MiddleInitial и Customer.Title, если можете объединить их как Customer.Name; к тому времени, когда вы подумаете о постоянстве, они, вероятно, будут иметь несколько полей в вашей базе данных, но вашей объектной модели все равно.


Куда подходят неразделенные изменяемые объекты? Если во всем юниверсе существует только одна ссылка на объект, идентичность объекта не будет иметь значения, даже если она изменяема. На мой взгляд, вещь является сущностью, если существует ссылка, которую можно использовать для наблюдения за аспектом состояния, которое может измениться без использования этой ссылки для его изменения . Если вещь не привязана к внешнему миру и либо она неизменна, либо существует только одна ссылка на нее в любом месте во вселенной, то описанный выше сценарий не может возникнуть, и это ценность.
supercat

Что-то вроде an int[1]может быть неразделенным изменяемым значением, совместно используемым неизменяемым значением (если ни одна из вещей, которые содержат ссылки, никогда не будет писать в него), или сущностью (если существуют две или более ссылок, и одна из них может использоваться для записи значения, которые можно прочитать с помощью другого). К сожалению, я не знаю никакой языковой поддержки в Java или .NET для предотвращения случайного превращения объектов класса, инкапсулирующих изменяемые значения в сущности.
supercat

@supercat, Если вы имеете в виду отсутствие прямой простой поддержки, я бы согласился, но я делаю это, устраняя публичный доступ к конструкторам, используя только статические фабрики для создания новых экземпляров и ограничивая весь доступ к состоянию через свойства только для чтения (без сеттеров) .
Чарльз Бретана

40

Любой объект, который в совокупности определяется всеми его атрибутами, является объектом значения. Если какой-либо из атрибутов изменится, у вас будет новый экземпляр объекта значения. Вот почему объекты значений определены как неизменяемые.

Если объект не полностью определен всеми своими атрибутами, тогда существует подмножество атрибутов, которые составляют идентичность объекта. Остальные атрибуты можно изменить без переопределения объекта. Этот тип объекта не может быть определен как неизменяемый.

Более простой способ провести различие - представить объекты значений как статические данные, которые никогда не изменятся, а объекты - как данные, которые развиваются в вашем приложении.


7

Типы значений:

  • Типы значений не существуют сами по себе, это зависит от типов сущностей.
  • Объект типа значения принадлежит объекту типа сущности.
  • Продолжительность жизни экземпляра типа значения ограничена продолжительностью жизни экземпляра сущности-владельца.
  • Три типа значений: базовый (примитивные типы данных), составной (адрес) и коллекция (карта, список, массивы)

Сущности:

  • Типы сущностей могут существовать сами по себе (Идентичность)
  • У сущности есть свой жизненный цикл. Он может существовать независимо от любого другого объекта.
  • Например: Человек, Организация, Колледж, Мобильный, Дом и т. Д. Каждый объект имеет свою индивидуальность.

Не имеет отношения к DDD :(
HydTechie

6

Я не знаю, верно ли следующее, но я бы сказал, что в случае объекта Address мы хотим использовать его как объект значения вместо объекта, потому что изменения объекта будут отражены на всех связанных объектах ( Человек, например).

Возьмем такой случай: вы живете в своем доме с другими людьми. Если бы мы использовали Entity для Address, я бы сказал, что был бы один уникальный Address, на который ссылаются все объекты Person. Если один человек съезжает, вы хотите обновить его адрес. Если вы обновите свойства объекта Address, у всех людей будут разные адреса. В случае объекта-значения мы не сможем редактировать адрес (поскольку он неизменяемый), и мы будем вынуждены предоставить новый адрес для этого человека.

Это звучит правильно? Я должен сказать, что я был / все еще смущен этой разницей после прочтения книги DDD.

Если пойти еще дальше, как это будет смоделировано в базе данных? Были бы у вас все свойства объекта Address в виде столбцов в таблице Person или вы бы создали отдельную таблицу Address, которая также имела бы уникальный идентификатор? В последнем случае люди, живущие в одном доме, будут иметь разные экземпляры объекта Address, но эти объекты будут одинаковыми, за исключением их свойства ID.


1
«Возьмем этот случай: вы живете в своем доме с другими людьми. Если бы мы использовали Entity для Address, я бы сказал, что будет один уникальный Address, на который ссылаются все объекты Person». Я думаю, что у каждого из этих людей есть собственный экземпляр Address, но они просто равны (похоже, у каждого из них может быть банкнота в 5 долларов, но это не значит, что это
Prokurors

«но это не означает, что это та же самая банкнота» - я полагаю, это зависит от того, назначают ли банкноте дополнительные свойства (например, дату выпуска, физическое местоположение в пространстве и т. д.); иначе они были бы такими же. И я думаю, то же самое и для программного обеспечения: адрес такой же или нет, в зависимости от свойств, которые нам нужны / мы хотим рассмотреть.
adrhc 01

4

адрес может быть сущностью или объектом значения, который зависит от рабочего процесса. Объект адреса может быть сущностью в приложении курьерской службы, но адрес может быть объектом значения в другом приложении. в курьерском приложении имеет значение идентичность адресного объекта


2

Я спрашивал об этом в другой ветке и думаю, что все еще запутался. Я могу путать соображения производительности с моделированием данных. В нашем приложении для каталогизации заказчик не меняется до тех пор, пока ему это не понадобится. Это звучит глупо, но количество «чтений» данных о клиентах намного превышает количество «операций записи», и поскольку многие веб-запросы попадают в «активный набор» объектов, я не хочу загружать клиентов снова и снова. Итак, я пошел по неизменной дороге для объекта Customer - загрузить его, кэшировать и обслуживать тот же самый для 99% (многопоточных) запросов, которые хотят видеть клиента. Затем, когда клиент что-то меняет, попросите «редактора» создать нового клиента и аннулировать старого.

Меня беспокоит, что если многие потоки видят один и тот же объект клиента и он изменчив, тогда, когда один поток начинает изменять, в других происходит хаос.

Теперь у меня проблемы: 1) разумно ли это и 2) как лучше всего это сделать, не дублируя много кода о свойствах.


1

3 различие между EntitiesиValue Objects

  • Идентификатор и структурное равенство: сущности имеют идентификатор, сущности одинаковы, если имеют одинаковый идентификатор. Объекты-значения вне руки имеют структурное равенство, мы считаем два объекта-значения равными, когда все поля одинаковы. Объекты значений не могут иметь идентификатора.

  • Изменчивость и неизменность: объекты-значения - это неизменяемые структуры данных, тогда как сущности меняются в течение своей жизни.

  • Продолжительность жизни: объекты-значения должны принадлежать сущностям


1

Очень простым предложением я могу сказать, что у нас есть три типа равенства:

  • Равенство идентификаторов : класс имеет поле идентификатора, и два объекта сравниваются со значением поля идентификатора.
  • Ссылочное равенство : если ссылка на два объекта имеет одинаковый адрес в памяти.
  • Структурное равенство : два объекта равны, если все их члены совпадают.

Равенство идентификаторов относится только к сущности, а структурное равенство относится только к объекту значения. На самом деле объекты-значения не имеют идентификатора, и мы можем использовать их взаимозаменяемо. также объекты-значения должны быть неизменными, а сущности могут быть изменяемыми, а объекты-значения не будут иметь никакой таблицы в базе данных.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.