Я понимаю, что шаблон репозитория абстрагирует постоянство объектов домена, позволяя разработчику читать / писать / удалять объекты из постоянного хранилища, не зная, как хранится объект (SQL, NoSQL, плоские файлы и т. Д.). Я очень люблю шаблон репозитория и нахожу, что он хорошо работает во многих ситуациях, например, абстрагируя бизнес-логику от логики постоянства, позволяя ленивую загрузку объектов, где это уместно, и т. Д.
Однако я не совсем понимаю, поддерживает ли объект репозитория ссылку на все объекты или нет? Например:
Repository repository;
std::shared_ptr<Person> pPerson = repository.retrievePersonById("bob");
p->updateDetails("Bob", "the Builder");
repository.savePerson(p);
repository
сохранить ссылку на Person
экземпляр вернулся? Да, спасибо Guillaume31 за аналогию в памяти.repository
удалить этот экземпляр Person
? Предположительно это когда счетчик ссылок достигает нуля.repository
больше не хранит внутреннюю ссылку на нее, она гидратирует свежую копию из базы данных, и у вас фактически есть два экземпляра Person
когда вы действительно должны ссылаться на тот же экземпляр? Учитывая, что ответом на вопрос Q1 было «Да», хранилище всегда поддерживает ссылку и поэтому всегда должно возвращать один и тот же объект..На самом деле я пишу PHP-приложение, несмотря на то, что приведенный выше пример написан на C ++.
Более подходящая метафора для хранилища может заключаться в том, что это иллюзия коллекции объектов в памяти. Возьмите свой базовый тип коллекции с любого языка OO. Если вы получаете элемент из этой коллекции и изменяете его, вам, как правило, не нужно впоследствии сохранять его обратно в коллекцию, потому что он никогда не переставал быть в коллекции.
То же самое касается хранилища — оно обслуживает объекты, может добавлять объекты к себе, но не предоставляет никаких возможностей для экономия изменения в базовом хранилище. Действительно, все дело в том, чтобы скрыть существование основного хранилища. Он также не предоставляет никаких методов для «обновления» состояния объекта, потому что объект, который он обслуживает, находится в памяти, и вы можете свободно изменять его, он никогда не будет синхронизирован.
Также лучше, если репозиторий будет держать руки подальше от управления транзакциями и фиксации единиц работы. Вы должны делегировать это клиенту (см. Проект, управляемый доменом, стр. 156).
Чтобы ответить на ваши вопросы, в рамках бизнес-транзакции вы не должны думать о свежести объектов, возвращаемых репозиторием. Они просто отражают состояния некоторых сущностей в определенный момент времени, все, что вам нужно сделать, это принять их такими, какие они есть, и использовать их. На более глобальном уровне некоторый внешний механизм (обычно инструмент ORM) предоставит вам возможность управлять тем, как вы изолируете свою небольшую бизнес-транзакцию от других, обычно в форме реализации Единицы работы. Сброс изменений в базу данных и обработка потенциальных проблем с устаревшими объектами — это не решение для запроса репозитория, а более глобальное решение на уровне бизнес-транзакции, которое должно произойти только тогда, когда вы решите, что ваш вариант использования завершен и вы хотите его зафиксировать.
Других решений пока нет …