Вот небольшая проблема
Иметь сущность со значением объекта. Не проблема. Я заменяю объект-значение новым, затем nhibernate вставляет новое значение и теряет значение старого, а затем удаляет его. Хорошо, это проблема.
Застрахованным является моя сущность в моем домене. У него есть коллекция адресов (объектов значения). Одним из адресов является MailingAddress. Когда мы хотим обновить почтовый адрес, скажем, почтовый индекс был неправильным, следуя доктрине г-на Эванса, мы должны заменить старый объект новым, так как он неизменный (верно, объект значения?).
Но мы не хотим удалять строку, потому что PK этого адреса является FK в таблице MailingHistory. Итак, следуя доктрине г-на Эванса, мы в значительной степени облажались. Если я не создаю адреса своих сущностей, мне не нужно «заменять» его и просто обновлять его член почтового индекса, как в старые добрые времена.
Что бы вы мне предложили в этом случае? На мой взгляд, ValueObjects полезны только тогда, когда вы хотите инкапсулировать группу столбцов таблицы базы данных (компонент в nhibernate). Все, что имеет постоянный идентификатор в базе данных, лучше сделать его сущностью (не обязательно совокупным корнем), чтобы вы могли обновлять ее элементы, не воссоздавая весь граф объектов, особенно если это объект с глубокой вложенностью.
Вы согласны? Разрешено ли мистеру Эвансом иметь изменяемый объект значения? Или объект изменяемого значения является кандидатом в сущность?
Спасибо
источник
Ответы:
Все, что имеет идентичность, должно быть сущностью, а все, что не имеет идентичности, является простым значением, следовательно, объектом значения.
По словам Мартина Фаулера (который в свою очередь цитирует Эрика Эванса)
Причина, по которой ваш адрес стал объектом значения:
Если ваш адрес изменчив, вы, вероятно, испортите свою историю рассылки в конце. Например, если вы отправляете товары клиенту, вы не можете быть уверены, на какой адрес вы действительно что-то отправляли в прошлом, если адрес, на который ссылается ваша таблица MailingHistory, был изменен.
Запись MailingHistory, которую мы отправили A764 по адресу 657, может означать, что вчера мы отправили статью A764 в Бостон, а завтра отправили статью A764 в Нью-Йорк .
Если почтовый адрес был изменен, нет необходимости удалять старый. Сохраните его и отметьте как неактивный , а новый как активный .
Конечно, вы можете рассматривать свой адрес как сущность, но только при обновлении он не изменит фактическое место, на которое ссылается адрес, а, следовательно, позволит только исправить опечатки.
Если вы уверены, что можете это сделать, то использование Entity будет возможно.
Но лучшее решение IMHO - не ссылаться на адрес Entity в вашей истории рассылки, а вместо этого сохранять конкретный адрес непосредственно в вашей таблице истории рассылки (в основном копируя данные адреса).
Таким образом, вы всегда будете знать, куда вы отправили свои материалы (или что вы отправляете по почте), и, поскольку вы будете использовать изменяемую сущность, ваша таблица адресов не будет загромождена.
Я работал с / на нескольких системах ERP, и почти все они использовали этот подход.
У вас будет некоторая избыточность в вашей базе данных, но это самый прагматичный способ, IMHO.
источник
ALTER
, использование сущностей в отдельных таблицах может оказаться необходимым. Это, в свою очередь, требует таких стратегий, как «всегда присоединяйся к новейшему адресу / телефону / электронной почте» в своихSELECT
запросах, которые сложно поддерживать и эффективно поддерживать . Сохраняйте это простым, если это вообще возможно.active
-flag. Конечно, вы должны всегда использовать ихand active = true
в своих объединениях, поддерживать флаг в актуальном состоянии и добавлять ограничения в свою таблицу, чтобы, например, только один адрес электронной почты для каждого клиента мог установить этот флаг в значение true.active=true
. Это не то, что я бы назвал простым, именно поэтому мне нравится ваше решение.Я вижу 2 вещи:
Допустимо ли изменение почтового индекса на запись истории? Я думаю, что было бы логично, чтобы запись истории указывала на старый неизмененный адрес, так что вы знаете, что отправляете его по неправильному адресу.
В тот момент, когда MailingHistory имеет FK на адресе, адрес перестает быть объектом значения и становится сущностью. Значимые объекты не имеют идентичности, что позволяет другим сущностям ссылаться на эту идентичность. Вы можете иметь адреса в одной таблице, на которую указывают другие таблицы, но единственным эффектом является экономия места. С точки зрения предметной области, если две сущности имеют ссылку на один и тот же тип объекта-значения, они не делятся какой-либо информацией.
источник
IMO объект адреса - это объект в вашем домене. Он разделяется несколькими сущностями, имеет собственную идентификацию и уникален для всей системы.
Эванс говорит:
источник