Должен ли репозиторий всегда возвращать одну и ту же ссылку в памяти при запросе одного и того же идентификатора? - PullRequest
0 голосов
/ 09 января 2019

Во многих блогах или статьях читается следующее утверждение о хранилище

Вы должны думать о хранилище как о коллекции объектов домена в памяти

Теперь я спрашиваю себя, что должно произойти, когда я дважды запрашиваю репозиторий для того же идентификатора.

Entity a = theRepo.GetById(1);
Entity b = theRepo.GetById(1);

assertTrue( a == b ); // Do they share the same reference ?
assertTrue( a.equals( b ) ); // This should always be true
  • Должно ли хранилище всегда возвращать одну и ту же ссылку в памяти?
  • Должно ли хранилище возвращать новый экземпляр сущности, но с равным состоянием?

Ответы [ 3 ]

0 голосов
/ 10 января 2019

На мой взгляд, ваша проблема сводится к продолжительности жизни хранилища. Хранилища являются временными (в идеале), а также, иногда, они живут внутри другого класса, называемого «Единица работы», который также является временным.

Я не думаю, что это проблема DDD, а скорее проблема инфраструктуры.

0 голосов
/ 12 января 2019

Для данного типа объекта хранилище представляет собой набор экземпляров данного типа объекта.

Хранилище не создает экземпляры сущности. Это просто набор (в смысле «набора») экземпляров, которые вы создали ранее. Затем вы добавляете эти экземпляры в хранилище (набор экземпляров). И вы можете получить эти экземпляры.

Набор не дублирует элементы. При наличии идентификатора (например, id = 1) у набора будет только один экземпляр с id = 1, и этот экземпляр будет тот, который вы получите, когда вызываете "theRepo.GetById (1)".

Итак:

Entity a = theRepo.GetById (1);

Entity b = theRepo.GetById (1);

Должно ли хранилище всегда возвращать одну и ту же ссылку в памяти?

См. ОБНОВЛЕНИЕ 3.

Должен ли репозиторий возвращать новый экземпляр сущности, но с равное состояние?

Нет. Репозиторий должен возвращать экземпляр, который вы добавили ранее. Хранилище не должно создавать новые экземпляры.

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

Вы смешиваете понятия. Репозиторий - это просто набор (набор) экземпляров. Экземпляры создаются фабриками (или методами конструктора сущности).

См. Книгу IDDD Вона Вернона (раздел «Коллекционно-ориентированные репозитории» в главе 12).

Надеюсь, это поможет.

UPDATE:

Когда я говорю «... Репозиторий - это набор экземпляров ...», я имею в виду, что он имитирует набор. Моя вина не выражает это хорошо. Что касается обновления экземпляра хранилища, такой операции не существует, поскольку, когда вы извлекаете экземпляр и изменяете его, изменения вносятся в экземпляр хранилища, вам не нужно повторно сохранять экземпляр. Механизм постоянства, реализующий репозиторий, должен иметь возможности для обеспечения такого поведения. См. Главу 12 книги «Реализация DDD» Вогна Вернона.

ОБНОВЛЕНИЕ 2:

Я хочу пояснить, что то, что я говорю здесь, - это мое понимание после прочтения книги IDDD Вона Вернона, а также другой книги («Проектирование доменов в PHP» Карлоса Буэносвиноса). Я вообще не пытаюсь вводить в заблуждение.

ОБНОВЛЕНИЕ 3:

Я задал Вону Вернону следующий вопрос:

По поводу репозитория, ориентированного на коллекцию, у меня есть вопрос: Если я сделаю Foo aFoo=fooRepository.getById(1); Foo anotherFoo=fooRepository.getById(1); тогда гарантируется, что обе ссылки одинаковы (aFoo == anotherFoo)?

И он ответил следующее:

Это зависит от механизма обеспечения сохранности, такого как Hibernate / JPA. Похоже, это следует делать, если вы используете один и тот же сеанс в обоих операциях чтения, и оба чтения имеют одинаковую область транзакций, но проверьте это с помощью ORM.

0 голосов
/ 09 января 2019

Не думаю, что вы можете предположить, что a == b.

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

С другой стороны, предполагая, что a или b не были впоследствии изменены после того, как они были извлечены из того же хранилища, можно с уверенностью предположить, что a.equals(b), также предполагая, что equals() метод был правильно реализован для объекта.

...