Подтвердить что ты не робот

Объекты Value в DDD - Почему неизменяемы?

Я не понимаю, почему объекты ценности в DDD должны быть неизменными, и я не вижу, как это легко сделать. (Я занимаюсь С# и Entity Framework, если это имеет значение.)

Например, рассмотрим классический объект значения адреса. Если вам нужно изменить "123 Main St" на "123 Main Street", почему мне нужно построить целый новый объект вместо того, чтобы сказать myCustomer.Address.AddressLine1 = "123 Main Street"? (Даже если Entity Framework поддерживает структуры, это все равно будет проблемой, не так ли?)

Я понимаю (я думаю) идею о том, что объекты ценности не имеют идентификатора и являются частью объекта домена, но может ли кто-нибудь объяснить, почему неизменяемость является хорошей вещью?


EDIT. Мой последний вопрос здесь действительно должен быть "Может ли кто-нибудь объяснить, почему неизменяемость - это хорошая вещь применительно к объектам Value?" Извините за путаницу!


РЕДАКТИРОВАТЬ. К clairfy, я не спрашиваю о типах значений CLR (типы ссылок vs). Я спрашиваю о концепции DDD более высокого уровня объектов Value.

Например, вот хакерский способ реализации неизменяемых типов значений для Entity Framework: http://rogeralsing.com/2009/05/21/entity-framework-4-immutable-value-objects. В принципе, он просто делает всех сеттеров частным. Зачем решать эту проблему?

4b9b3361

Ответ 1

Игнорируйте все сумасшедшие ответы на тему безопасности потоков и т.д., что не имеет ничего общего с DDD. (Я еще не видел потокобезопасного O/R-карты или другого дружественного DDD файла)

Представьте объект значения для весов. скажем, у нас есть объект значения KG.

образец (отредактированный для ясности):

var kg75 = new Weight(75);
joe.Weight = kg75;
jimmy.Weight = kg75;

Теперь, что произойдет, если мы сделаем следующее:

jimmy.Weight.Value = 82;

Это также изменило бы вес joe, если мы все еще будем использовать те же ссылки на объекты. Обратите внимание, что мы назначили объект, представляющий 75 кг, для joe и jimmy. Когда jimmy набирает вес, изменился не объект kg75, это изменился вес jimmys, поэтому мы должны создать новый объект, представляющий 82 кг.

Но что, если у нас есть новый сеанс и загрузка как joe, так и jimmy в чистом UoW?

 var joe = context.People.Where(p => p.Name = "joe").First();
 var jimmy = context.People.Where(p => p.Name = "jimmy").First();
 jimmy.Weight.Value = 82;

Что тогда будет? так как EF4 в вашем случае будет загружать joe и jimmy и их веса без какой-либо идентификации, мы получим два разных весовых объекта, и когда мы изменим вес jimmys, joe все равно будет так же, как и раньше.

Таким образом, у нас было бы два разных поведения для одного и того же кода. если ссылки obejct все те же, то и joe, и jimmy получат новый вес. если joe и jimmy загружены в чистую uow, на изменение повлияет только одно из них.

И это было бы весьма неустойчивым imo.

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

Ответ 2

Почему 6 неизменяемых?

Поймите это, и вы поймете, почему объекты Value должны быть неизменными.

Изменить: теперь я верну свой диалог в этот ответ.

6 является неизменным, поскольку идентификация 6 определяется тем, что она представляет, а именно состоянием шести из чего-то. Вы не можете изменить, что 6 представляет это. Теперь это фундаментальная концепция объектов Value. Их значение определяется их состоянием. Сущность, однако, не определяется ее состоянием. A Customer может изменить свою фамилию или свой адрес и по-прежнему быть тем же самым Customer. Вот почему объекты Value должны быть неизменными. Их состояние определяет их личность; если их состояния меняются, их личность должна измениться.

Ответ 3

Я очень опаздываю на вечеринку, но мне было интересно об этом. (Поблагодарили бы за любые комментарии.)

Я не думаю, что это явно указано здесь, но я думаю, что ссылки Эванса на неизменность были в основном в контексте обмена:

чтобы обеспечить безопасный доступ к объекту, он должен быть неизменным: он не могут быть изменены за исключением полной замены. (Эванс p100)

В книге Эвана также есть боковая панель, называемая "Адрес объекта ценности? Кто спрашивает?".

Если соседи по комнате звонят, чтобы заказать электрическую услугу [т.е. если у двух клиентов был тот же адрес], компания нужно осознать это. [So] Адрес - это сущность. (Эванс p98)

В приведенном вами примере предположим, что домашний и домашний адрес клиента были 123 Main Street. Когда вы сделаете исправление, которое вы описали, изменились бы оба адреса? Если это так, и если я правильно читаю Эванса, это звучит так, будто у вас действительно есть сущность.

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

public class FullName
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

public class Customer
{
    public FullName Name { get; set; }
}

Без объекта значения следующее:

[Test]
public void SomeTest() {
    var fullname = new FullName { FirstName = "Alice", LastName = "Jones" };
    var customer1 = new Customer { Name = fullname };
    var customer2 = new Customer { Name = fullname };

    // Customer 1 gets married.
    customer1.Name.LastName = "Smith";

    // Presumably Customer 2 shouldn't get their name changed.
    // However the following will fail.
    Assert.AreEqual("Jones", customer2.Name.LastName);
}

Что касается преимуществ в целом, некоторые из них подхватываются в В DDD, каковы фактические преимущества объектов значений?. Примечательно, что вам нужно только проверить VO на создание. Если вы это сделаете, значит, вы всегда это знаете.

Ответ 4

Это может быть не полный ответ. Я только отвечаю на ваш вопрос о преимуществах неизменности.

  • Поскольку неизменяемые объекты являются нитями безопасно. Поскольку они не могут изменить государства, они не могут быть повреждены помехи или наблюдаемые в несогласованное состояние.
  • Ссылки на неизменяемые объекты могут быть легко разделены или кэшироваться без необходимости копировать или клонировать их, поскольку их состояние не может быть изменился после строительства.
  • Для получения дополнительных преимуществ неизменяемости вы смотрите здесь (LBushkin ответ) В чем преимущество непрерывности String?

Это пример Мартина Фаулера о том, почему объекты ценности должны быть неизменными.

Хорошо, в то время как необязательно делать VO неизменным (даже в книге DDD не говорится, что они должны быть неизменными), основная идея в DDD сделать его VO, похоже, не в том, чтобы иметь дело с жизнью циклические сложности, подобные сложностям сущности. Смотрите для более подробной информации.

Ответ 5

Объекты Value должны быть неизменными.

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

Давайте рассмотрим объект value как изменяемый.

class Name{
string firstName,middleName,lastName
....
setters/getters
}

Скажем, ваше оригинальное имя было Ричард Томас Кук

Теперь скажем, вы меняете только firstName (на Martin) и lastName (на Bond), Если это не неизменный объект, вы будете использовать методы для изменения состояния один за другим. Шансы иметь имя как Мартин Томас Кук в этом состоянии Aggregate до окончательного имени Мартина Томаса Бонда никогда не бывает приемлемым (также он дает неправильное представление тому, кто смотрит код позже, что приводит к нежелательному эффекту домино в дальнейшем дизайне).

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