DDD: Репозитории - это коллекции объектов в памяти?

Я заметил, что репозиторий обычно реализуется одним из следующих способов:

Способ 1

void Add(object obj);
void Remove(object obj);
object GetBy(int id); 

Способ 2

void Save(object obj);     // Used both for Insert and Update scenarios
void Remove(object obj);
object GetBy(int id);

Метод 1 имеет семантику коллекции (так определяются репозитории). Мы можем получить объект из хранилища и изменить его. Но мы не говорим коллекции, чтобы обновить ее. Реализация репозитория таким способом требует другого механизма для сохранения изменений, внесенных в объект в памяти. Насколько я знаю, это делается с помощью Unit of Work. Однако некоторые утверждают, что UoW требуется только тогда, когда вам нужен контроль транзакций в вашей системе.

Способ 2 устраняет необходимость иметь UoW. Вы можете вызвать метод Save(), и он определяет, является ли объект новым и должен ли он быть вставлен или изменен и должен быть обновлен. Затем он использует средства отображения данных для сохранения изменений в базе данных. Хотя это значительно облегчает жизнь, смоделированный репозиторий не имеет семантики коллекции. Эта модель имеет семантику DAO.

Я действительно смущен по этому поводу. Если репозитории имитируют коллекцию объектов в памяти, мы должны смоделировать их в соответствии с методом 1.

Что вы думаете об этом?

Мош

2 ответа

Лично у меня нет проблем с тем, что модель "Единица работы" является частью решения. Очевидно, вам это нужно только для CUD в CRUD. Однако тот факт, что вы реализуете шаблон UoW, лишь указывает на то, что у вас есть набор операций, которые нужно выполнять как пакет. Это немного отличается от того, чтобы сказать, что это должно быть частью транзакции. Если вы достаточно хорошо абстрагируете свои репозитории, ваша реализация UoW может не зависеть от используемого вами механизма поддержки - будь то база данных, XML и т. Д.

Что касается конкретного вопроса, я думаю, что разница между методом один и методом два тривиальна, если ни по какой другой причине, кроме большинства экземпляров метода два, нет проверки, чтобы увидеть, установлен ли идентификатор. Если установлено, обрабатывать как обновление, иначе рассматривать как вставку. Эта логика часто встроена в репозиторий и, на мой взгляд, больше для упрощения предоставляемого интерфейса. Цель репозитория - разбить объекты между потребителем и источником данных и устранить необходимость непосредственного знания источника данных. Я использую второй метод, потому что доверяю простой логике определения идентификатора, а не необходимости полагаться на отслеживание состояний объекта во всем приложении.

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

Может быть, вы хотите иметь:

T Persist(T entityToPersist);
void Remove(T entityToRemove);

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

Другие вопросы по тегам