Об'єкти DDD та цінності. Чи є об'єкти цінності, що змінюються, хорошим кандидатом для негр. Root Entity?


9

Тут невелика проблема

Мати сутність з об'єктом значення. Не проблема. Я замінюю ціннісний об'єкт на новий, після чого nhibernate вставляє нове значення та осиротіє старе, а потім видаляє його. Гаразд, це проблема.

Застрахована - моя особа в моєму домені. У нього є колекція адрес (об'єктів цінності). Одна з адрес - адреса MailingAddress. Коли ми хочемо оновити поштову адресу, скажімо, поштовий індекс був неправильним, дотримуючись доктрини містера Еванса, ми повинні замінити старий об’єкт на новий, оскільки він непорушний (ціннісний об'єкт правда?).

Але ми не хочемо видаляти рядок you, тому що PK цієї адреси є FK в таблиці MailingHistory. Отже, слідуючи доктрині містера Еванса, ми тут дуже сильно накручені. Якщо я не роблю свої адреси Entities, тому мені не доведеться "замінювати" його, а просто оновлювати його поштовий індекс, як і старі добрі дні.

Що б ви запропонували мені в цьому випадку? Як я бачу, ValueObjects корисні лише тоді, коли ви хочете інкапсулювати групу стовпців таблиці баз даних (компонент у nhibernate). Все, що має ідентифікатор стійкості в базі даних, краще зробити це Entity (не обов'язково сукупний корінь), щоб ви могли оновити його членів, не відтворюючи весь графік об'єкта, особливо якщо це об'єкт з глибоким вкладом.

Ви згодні? Чи дозволено містеру Евансу мати об'єкт, що змінюється? Або об'єкт змінного значення є кандидатом на суб'єкт господарювання?

Дякую


2
Чи існує таке поняття, як "об'єкт, що змінюється, значення"? У мене завжди було враження, що об'єкти цінності незмінні.
herby

@herby Я здогадуюсь, що у вас може бути кодовий об'єкт, що представляє об’єкт значення DDD у коді, але вам доведеться врахувати, що коли ви мутуєте об'єкт, він більше не посилається на той самий логічний об'єкт значення DDD, а на новий. Це може бути бажано, але це рецепт плутанини, який може змінити значення об'єктів, незмінних у коді, - це розумна умова.
MattDavey

Відповіді:


8

Все, що має тотожність, повинно бути Сутністю, і все, що не має ідентичності, є простою цінністю, отже, ціннісним об’єктом.

Цитувати Мартіна Фаулера (який, у свою чергу, цитує Еріка Еванса)

  • Сутність: Об'єкти, що мають чітку ідентичність, що проходить через час та різні уявлення. Ви також чуєте ці називані "довідкові об'єкти".
  • Ціннісний об’єкт: Об'єкти, які мають значення, мають лише поєднання їх атрибутів.

Причина зробити вашу адресу об’єктом цінності:

Якщо ваша адреса може змінюватися, ви, ймовірно, закінчите свою історію розсилки. Наприклад, якщо ви доставляєте товари клієнту, ви не можете бути впевнені, за якою адресою ви фактично щось відвантажили, якщо адреса, на яку посилається таблиця MailingHistory, була змінена.

Запис MailingHistory Ми вантажили A764 на адресу 657 може означати Ми вантажили статтю A764 в Бостон вчора і Ми вантажили статтю A764 в Нью - Йорк завтра.

Якщо поштову адресу потрібно змінити, не потрібно видаляти стару. Зберігайте його та позначте його як неактивне , а нове - як активне .


Звичайно, ви можете ставитися до своєї адреси як до Сутності, але лише при її оновленні це не змінить фактичного місця, на яке йдеться адреса, отже, лише дозволяючи виправляти помилки друку.

Якщо ви впевнені, що можете переконатися, що використання Entity було б можливим.


Але найкращим рішенням IMHO є не посилатись на адресу сутності в історії розсилки, а зберегти конкретну адресу безпосередньо в таблиці історії розсилки (в основному копіюючи дані адреси).

Таким чином, ви завжди знаєте, куди ви відправляли свої речі (або що ви надсилаєте), і оскільки ви будете використовувати об'єкт із змінною суттю, ваша адресна таблиця не буде захаращена.

Я працював з / над кількома ERP системами, і майже всі вони використовували цей підхід.

У вас буде деяка надмірність у вашій базі даних, але це найбільш прагматичний спосіб IMHO.


Це, мабуть, найголовніше рішення. Тільки якщо ви очікуєте, що майбутні канали зв’язку потребуватимуть додаткових стовпців, а ваша база даних занадто велика, щоб ALTERвикористовувати об’єкти в окремих таблицях. Це, в свою чергу, вимагає стратегій типу "завжди приєднуйтесь до новітньої адреси / телефону / електронної пошти" у ваших SELECTзапитах, які є складними для збереження ремонту та ефективності. Нехай це буде просто, якщо це взагалі можливо.
Тимо

@Timo "завжди приєднуйся до новітньої адреси / телефону / електронної пошти" - не важко, якщо ти денормалізуєш свої дані, просто додавши active-flag. Звичайно, ви повинні обов’язково використовувати його and active = trueу своїх приєднаннях, постійно оновлювати прапор та додавати контракт до свого столу, щоб, наприклад, лише одна електронна пошта для кожного клієнта могла встановити цей прапор істинним.
лень

Це вводить проблему дезактивації попередньої. Якщо ви замінили в коді "поточний" об'єкт адреси вашого коду і переходите до коду доступу до даних, то він не дізнається (1), чи є новий, чи ні (2) який потенційний старий один був. Таким чином, для кожної операції збереження доведеться робити щось складне, як-от "спочатку перейдіть і деактивуйте всі пов'язані адреси в базі даних", а потім збережіть поточну active=true. Це не те, що я б назвав простим, саме тому мені подобається ваше рішення.
Тимо

2

Я бачу 2 речі:

  1. Чи гаразд зміна поштового індексу впливає на запис історії? Я думаю, що було б логічно, щоб запис історії вказував на стару незмінну адресу, тож ви знаєте, що ви відправляєте її на неправильну адресу.

  2. У той момент, коли MailingHistory має FK за адресою, адреса перестала бути об'єктом цінності та стала сутністю. Об'єкти значення не мають ідентичності, що дозволяє іншим суб'єктам посилатися на цю ідентичність. Ви можете мати адреси в одній таблиці з іншими таблицями, що вказують на неї, але єдиним ефектом є економія місця. З точки зору домену, якщо два об'єкти мають посилання одного об'єкта значення, вони не поділяють будь-яку інформацію.


2

Об'єктом адреси IMO є об'єкт у вашому домені. Її поділяють декілька організацій, мають власну ідентичність та унікальні у всій системі.

Еванс каже:

Об'єкт, визначений головним чином його ідентичністю, називається сутністю.


Ідентичність домену, наскільки я розумію, не має нічого спільного з постійною ідентичністю. За книгою містера Евана.
Пепіто Фернандес

Ти правий. Я редагую свою відповідь. Я маю на увазі те, що адреса об’єкта має значення в цій конкретній області, вона унікальна. ІМО, зовнішній та первинний ключ - це знак того, що він насправді є унікальним об’єктом у всій області, тому він має ідентичність.
маргабіт

1
"об’єкт адреси ... має власну ідентичність" - який атрибут адреси однозначно ідентифікує? Жоден атрибут адреси не є унікальним, але комбінація атрибутів служить ідентичністю. Це саме визначення об’єкта значення
MattDavey

@MattDavey: це вдалий висновок, але я заплутався, коли Тоні каже: "Ми не хочемо видаляти рядок, який ти, тому що PK цієї адреси є ФК у таблиці MailingHistory". Це означає для мене, що об’єкт Address також має значення поза агрегатом «Застрахований». Що вказує на мене, що об'єкт 'Address' не повинен бути ValueObject. Як ти гадаєш?
маргабіт

Чи можемо ми сказати, що об'єкти цінності незмінно матимуть повну власність (UML) з боку батьків? Крім того, ціннісний об’єкт не матиме сенсу без його батьків і не може бути поділений між батьками?
Сударшан
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.