Я пишу 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 должна быть автоматически сохранена репозиторием, чтобы следующий запрос возвращал правильную коллекцию, не strong>, содержащий исходный объект Person.
Но разве это не роль единицы работы — решать, какую модель сохранять в базе данных и когда?
В приведенной выше реализации репозиторий должен принять решение о сохранении ранее полученного объекта Person при получении другого вызова find(), чтобы результат соответствовал модификации. Но если бы не было другого вызова find(), модель вообще не сохранялась бы неявно.
В контексте единицы работы это на самом деле не проблема, потому что мы можем начать транзакцию в начале и в любом случае откатить любую вставку в базу данных, если это необходимо. Но не может ли этот репозиторий при самостоятельном использовании привести к неожиданному и непредсказуемому поведению?