Я бы не ставил слишком много логики на сущности.Они должны заботиться о своем собственном состоянии, например.заботиться о согласованности собственных полей.Но они не должны заботиться о последовательности во всей системе.ИМХО, ваш пример «user.AddOrder», который устанавливает состояние пользователя, заходит слишком далеко.
Вы также теряете возможность повторного использования ваших сущностей, если они все делают.Если вы получаете дополнительные требования (например, дополнительные ситуации, такие как импорт данных, новый тип заказа, новый тип правила), ваша модель сущности мешает, она недостаточно гибкая.
Это отсутствие гибкостиобнаруживается в модульных тестах.Когда вы изолируете классы в модульных тестах, становится ясно, что на самом деле инкапсулировано и больше не может быть разделено.Если у вас возникнут проблемы, ваша инкапсуляция, скорее всего, не очень полезна.Таким образом, модульные тесты являются отличным доказательством возможности повторного использования.
Пример (псевдокод, не против, если я пропущу смысл вашего приложения, просто покажу, к чему относится логика):
class User
{
AccountState State { get; }
void MakeTopSeller()
}
class Order
{
decimal GetTotal();
User Salesman { get; }
}
class OrderService
{
void AddOrder()
{
// ....
if (order.GetTotal() > ToSellerAmount)
{
order.Salesman.MakeTopSeller();
}
}
}
Редактировать : Если вы все еще считаете, что ваш подход является подходящим (я имею в виду, я не могу определиться с тем, что я знаю об этом), вам не нужно его менять.Но если ваша сущность использует другую сущность для установки состояния, и вам нужно это состояние в тесте, вам нужно сделать все это в тесте: создать заказ и добавить его пользователю.
Существует еще одинспособ расколоть вещи.Вы можете поместить правило в отдельный класс, например.используя шаблон стратегии.Обычно сложно установить стратегии для сущностей, потому что базовый уровень базы данных должен внедрить их.