Ожидаемое поведение репозитория - PullRequest
0 голосов
/ 18 мая 2011

Я пишу ORM и не уверен в ожидаемом поведении Репозитория, или, точнее, границы между Репозиторием и Единицей Работы.Насколько я понимаю, хранилище может выглядеть так:

interface IPersonRepository
{
    public function find(Criteria criteria);
    public function add(Person person);
    public function delete(Person person);
}

Согласно Фаулеру ( PoEAA , стр. 322):

Репозиторий является посредником междууровни отображения доменов и данных, действующие как набор объектов домена в памяти.[...] Объекты могут добавляться и удаляться из репозитория, как и из простой коллекции объектов.

Это будет означать, что следующий тест должен работать (при условии, что у нас уже естьПерсона сохранилась, чья фамилия Фаулер):

collection = repository.find(lastnameEqualsFowlerCriteria);
person = collection[0];

assertEquals(person.lastname, "Fowler");

person.lastname = "Evans";
newCollection = repository.find(lastnameEqualsFowlerCriteria);

assertFalse(newCollection.contains(person));

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

Но разве это не роль Единицы работы, чтобы решить, какая модельдля сохранения в базе данных, и когда?

В описанной выше реализации репозиторий должен решить сохранить Персона, ранее извлеченную при получении другого вызова find (), чтобы результат соответствовал модификации.Но если бы не был выполнен какой-либо другой вызов find (), модель вообще не сохранялась бы неявно.

В контексте единицы работы это на самом деле не проблема, потому что мы можем начать транзакциюв начале и откатить любую вставку в БД в любом случае, если это необходимо.Но может ли этот репозиторий, если он используется один, привести к неожиданному, непредсказуемому поведению?

Ответы [ 2 ]

1 голос
/ 19 мая 2011

Репозиторий является посредником между доменом и слоями отображения данных, действуя как коллекция объектов домена в памяти.[...] Объекты могут быть добавлены и удалены из репозитория, как и из простой коллекции объектов.

Это не означает, что вам не нужен метод сохранения.Вам все еще нужно явно зафиксировать свои изменения в хранилище.

См. Шаблон единицы работы и невежество в постоянстве

public interface IUnitOfWork {
  void MarkDirty(object entity);
  void MarkNew(object entity);
  void MarkDeleted(object entity);
  void Commit();
  void Rollback();
}

В некотором смысле вы можете думать оЕдиница работы как место для выгрузки всего кода обработки транзакций.В обязанности Единицы работы входит:

  • Управление транзакциями.
  • Заказ вставок, удалений и обновлений базы данных.
  • Предотвращение дублирования обновлений.Внутри одного использования объекта Unit of Work различные части кода могут помечать один и тот же объект Invoice как измененный, но класс Unit of Work будет выдавать только одну команду UPDATE для баз данных
0 голосов
/ 09 июня 2011

Я думаю, что вы спрашиваете о следующем: http://martinfowler.com/eaaCatalog/identityMap.html

Репозиторий должен хранить извлеченные объекты в памяти, и все последующие вызовы для этого объекта не должны извлекаться из постоянного хранилища, поэтому ваш пример должен работатьхорошо.

...