Общий вопрос разработки ORM - PullRequest
4 голосов
/ 05 мая 2010

Предположим, у вас есть 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. Человек и Кролик могут иметь ссылки друг на друга
  2. Любые действия над 1 объектом также могут изменить состояние другого объекта.
  3. Даже если никакие явные действия не выполняются, в объектах все равно может быть изменение состояния (например, кролик может умереть от голода, и это приведет к его удалению из массива Person.rabbits)

Что касается DDD, я думаю, что правильный подход - синхронизировать все вызовы, которые могут изменить состояния в доменной модели. Например, если Person покупает Кролика, ему / ей потребуется приобрести блокировку Person, чтобы внести изменения в массив кроликов, а также другую блокировку в Rabbit, чтобы сменить своего владельца, прежде чем освободить первый. Это предотвратило бы состояние гонки, когда 2 человека утверждают, что являются владельцем маленького Кролика.

Другой подход состоит в том, чтобы позволить базе данных обрабатывать все эти синхронизации. Кто делает первый вызов, выигрывает, но затем БД должна иметь какую-то бизнес-логику, чтобы выяснить, является ли она действительной транзакцией (например, если у Кролика уже есть владелец, он не может сменить своего владельца, если человек не отдает его) .

В обоих подходах есть свои плюсы и минусы, и я ожидаю, что «лучшее» решение будет где-то посередине. Как бы вы сделали это в реальной жизни? Какой у тебя опыт и опыт?

Кроме того, действительно ли существует опасение, что может быть другое состояние гонки, когда модель домена зафиксировала свое изменение, но до того, как она будет полностью зафиксирована в базе данных?

И для 3-го наблюдения (т.е. изменение состояния из-за фактора времени). Как ты это сделаешь?

Ответы [ 2 ]

1 голос
/ 05 мая 2010

1, это может или не может быть практичным для кролика, чтобы знать его владельца, в определенных контекстах животные знают своих владельцев по тегам или микрочипированию .... в DDD вы моделируете, что имеет смысл в контексте вашей конкретной области , Но хорошо, что они знают друг о друге. Вы захотите сделать замки для передачи права собственности. Это относительно просто с большинством ORM

третий. Конечно, владелец владеет мертвым кроликом? Но достаточно просто, как часть убийства кролика, вы удаляете его от его владельца. Что касается того, что убивает кролика, возможно, вам нужен класс GrimReaper, который запланирован своевременно, чтобы посмотреть на все ILivingThings и работает, если условия жизни были поддержаны, если не ILivingThing.Slaughter (). Reap ();

1 голос
/ 05 мая 2010

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

  • В действительности, должен ли кролик знать, кто его владелец?То есть нужна ли ссылка?Если вы пытаетесь смоделировать домен, маловероятно, что кролик знает, кто его владелец (и что, если его разделяют два человека)?
  • Должен ли человек иметь ссылку на кролика напрямую?Или вы думаете, что имеет больше смысла иметь более общий интерфейс, такой как Animal?Не похоже, что эти операции относятся к конкретному кролику?
  • Что касается потоков и синхронизации, является ли ваше приложение многопоточным?Возможно ли, чтобы в вашем приложении два человека пытались одновременно быть владельцем кролика?Например, если вы моделировали зоомагазин, это не могло бы произойти (также, если у Кролика не было ссылки на его владельца, эта проблема, возможно, больше не существовала).
  • Если оба объекта действительно нуждаются в ссылках друг на друга, я бы, вероятно, выполнил синхронизацию на уровне объекта (с блокировками).Поскольку вы можете обновить модель домена в памяти, а затем сохранить ее в базе данных (возможно, при завершении работы приложения или в другом случае, если это приложение для настольного компьютера), вы всегда хотите, чтобы память находилась в согласованном состоянии.
  • В общем,начать с самого простого решения и рефакторинга по мере необходимости.Учитывая ваш вопрос и то, где вы находитесь в разработке, я считаю очень маловероятным, что разница в синхронизации на уровне объектов или в базе данных, скорее всего, будет связана с производительностью.
...