можно ли сделать DDD без ORM?
Да, но ORM упрощает вещи.
Если честно, я думаю, что ваша проблема не в том, нужен ли вам ORM или нет, а в том, что вы слишком много думаете о данных, а не о поведении, что является ключом к успеху с DDD. С точки зрения модели данных, большинство сущностей будут иметь ассоциации с большинством других сущностей в той или иной форме, и с этой точки зрения вы можете обойти всю модель. Вот как это выглядит с вашим клиентом и заказами и, возможно, поэтому вы думаете, что вам нужна ленивая загрузка. Но вам нужно использовать агрегаты, чтобы разбить эти отношения на поведенческие группы.
Например, почему вы смоделировали совокупность клиентов, чтобы получить список заказов? Если ответ «потому что у клиента могут быть заказы», то я не уверен, что вы настроены на DDD.
Какое поведение требует, чтобы у клиента был список заказов? Когда вы больше задумываетесь о поведении вашего домена (то есть какие данные требуются в какой момент), вы можете смоделировать ваши агрегаты на основе вариантов использования, и все станет намного понятнее и проще, так как вы отслеживаете изменения только для небольшого набора объектов. в совокупной границе.
Я подозреваю, что Клиент должен быть отдельным агрегатом без списка заказов, а Заказ должен быть агрегатом со списком строк заказа. Если вам необходимо выполнить операции с каждым заказом для клиента, используйте orderRepository.GetOrdersForCustomer (customerID); внесите изменения, затем используйте orderRespository.Save (order);
Что касается отслеживания изменений без ORM, есть несколько способов сделать это, например, агрегат заказов может вызывать события, которые репозиторий заказов прослушивает для удаленных строк заказа. Затем они могут быть удалены, когда единица работы завершена. Или чуть менее элегантный способ - поддерживать удаленные списки, то есть order.DeletedOrderLines, которые, очевидно, может прочитать ваш репозиторий.
Подводя итог:
- Я думаю, вам нужно больше думать о поведении, чем о данных
- ORM облегчает отслеживание изменений, но вы можете сделать это без него, и вы определенно можете сделать DDD без него.
РЕДАКТИРОВАТЬ в ответ на комментарий:
Не думаю, что я бы реализовал ленивую загрузку для строк заказа. Какие операции вы можете выполнить с заказом без необходимости в строках заказа? Не много я подозреваю.
Однако я не должен ограничиваться «правилами» DDD, когда это, кажется, не имеет смысла, так что ... Если в маловероятном сценарии есть ряд операций, выполняемых над заказом В объекте, для которого не нужно заполнять строки заказа И , часто существует большое количество строк заказа, связанных с заказом (оба должны быть верны, чтобы я считал это проблемой) сделать это:
Имейте это личное поле в объекте заказа:
private Func<Guid, IList<OrderLine>> _lazilyGetOrderLines;
Что будет передано хранилищем заказов в заказ на создание:
Order order = new Order(this.GetOrderLines);
Где это закрытый метод в OrderRepository:
private IList<OrderLine> GetOrderLines(Guid orderId)
{
//DAL Code here
}
Тогда свойство в строках заказа может выглядеть так:
public IEnumberable<OrderLine> OrderLines
{
get
{
if (_orderLines == null)
_orderLines = _lazilyGetOrderLines(this.OrderId);
return _orderLines;
}
}
Редактировать 2
Я нашел этот пост в блоге, который имеет подобное решение, но немного более элегантный:
http://thinkbeforecoding.com/post/2009/02/07/Lazy-load-and-persistence-ignorance