Предположим, у вас есть 2 класса, Персона и Кролик. Человек может сделать несколько вещей с кроликом, он может либо накормить его, купить его и стать его владельцем, либо отдать его. Кролик не может иметь ни одного, или не более одного владельца одновременно. И если его не кормить какое-то время, он может умереть.
Class Person
{
Void Feed(Rabbit r);
Void Buy(Rabbit r);
Void Giveaway(Person p, Rabbit r);
Rabbit[] rabbits;
}
Class Rabbit
{
Bool IsAlive();
Person pwner;
}
Есть пара наблюдений из модели предметной области:
- Человек и Кролик могут иметь ссылки друг на друга
- Любые действия над 1 объектом также могут изменить состояние другого объекта.
- Даже если никакие явные действия не выполняются, в объектах все равно может быть изменение состояния (например, кролик может умереть от голода, и это приведет к его удалению из массива Person.rabbits)
Что касается DDD, я думаю, что правильный подход - синхронизировать все вызовы, которые могут изменить состояния в доменной модели. Например, если Person покупает Кролика, ему / ей потребуется приобрести блокировку Person, чтобы внести изменения в массив кроликов, а также другую блокировку в Rabbit, чтобы сменить своего владельца, прежде чем освободить первый. Это предотвратило бы состояние гонки, когда 2 человека утверждают, что являются владельцем маленького Кролика.
Другой подход состоит в том, чтобы позволить базе данных обрабатывать все эти синхронизации. Кто делает первый вызов, выигрывает, но затем БД должна иметь какую-то бизнес-логику, чтобы выяснить, является ли она действительной транзакцией (например, если у Кролика уже есть владелец, он не может сменить своего владельца, если человек не отдает его) .
В обоих подходах есть свои плюсы и минусы, и я ожидаю, что «лучшее» решение будет где-то посередине. Как бы вы сделали это в реальной жизни? Какой у тебя опыт и опыт?
Кроме того, действительно ли существует опасение, что может быть другое состояние гонки, когда модель домена зафиксировала свое изменение, но до того, как она будет полностью зафиксирована в базе данных?
И для 3-го наблюдения (т.е. изменение состояния из-за фактора времени). Как ты это сделаешь?