Являются ли репозитории Doctrine2 хорошим местом для сохранения моих сущностей?

42

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

Никогда не бывает примеров, в которых у репозиториев есть методы, такие как insertUser(User $user) или updateUser(User $user).

Однако при использовании SOA служба не должна работать с Entity Manager (это право, не так ли?), поэтому:

  • Должен ли мой сервис знать глобальный EntityManager?
  • Если моя служба знает только о используемых репозиториях (скажем, UserRepository и ArticleRepository)

Из этого обоих вопросов, еще один, должен ли мой сервис когда-либо явно persist() и flush() мои сущности?

Теги:
design-patterns
doctrine2
service-layer
soa

3 ответа

34
Лучший ответ

Да, репозитории обычно используются только для запросов.

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

Сам сервисный уровень отлично подходит для понимания уровня сохранения: сущности или менеджеры документов, репозитории и т.д.

Здесь приведен код, чтобы сделать его понятным:

class UserController
{
    public function indexAction()
    {
        $users = $this->get('user.service')->findAll();
        // ...
    }

    public function createAction()
    {
        // ...
        $user = new User();
        // fill the user object here
        $this->get('user.service')->create($user);
        // ...
    }
}

class UserService
{
    const ENTITY_NAME = 'UserBundle:User';

    private $em;

    public function __construct(EntityManager $em)
    {
        $this->em = $em;
    }

    public function findAll()
    {
        return $this->em->getRepository(self::ENTITY_NAME)->findAll();
    }

    public function create(User $user)
    {
        // possibly validation here

        $this->em->persist($user);
        $this->em->flush($user);
    }
}
  • 0
    Мне любопытно, как вы реализуете это (при сохранении на уровне службы.) Обычно я создаю и сохраняю сущности из контроллера, но допускаю, что это не кажется «правильным». Используете ли вы 1 сервис на организацию, которая нуждается в сохранении? Не могли бы вы углубиться в детали?
  • 9
    Сохранение в уровне контроллера не кажется правильным, потому что контроллеры должны беспокоиться только о графическом интерфейсе, то есть они просто анализируют запросы, делегируют всю «реальную» работу на уровень обслуживания и возвращают ответы. Большую часть времени у меня есть сервис для каждой сущности / документа, но это не правило, потому что иногда вы можете иметь сервисы без сущностей вообще и теоретически (я там еще не был) сервисы, которые управляют несколькими сущностями.
Показать ещё 9 комментариев
3

Если вы посмотрите на шаблон репозитория http://martinfowler.com/eaaCatalog/repository.html,

указано, что репозитории используют "подобный сборке интерфейс".

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

Я не говорю, что это библия, но концептуально ничего плохого не видеть в репозитории, как в коллекции, которую вы можете запросить. Но поскольку это коллекция, вы можете добавлять, удалять,... Фактически ObjectRepository должен реализовать Doctrine\Common\Collection:)

С другой стороны, самое главное - не испортить чтение и запись, как говорит CQS. Возможно, поэтому они не позволили прямо так, чтобы избежать злоупотреблений и читать/писать микс.

EDIT: Мне следовало поговорить о flush. Это должно не быть сделано в самом репозитории, так как это может нарушить последовательность транзакций.

Лучше переместить вызов flush на то, что обертывает всю логику бизнес-транзакций (командная шина обрабатывает команду f.e?)

  • 0
    Я думаю, что вы, возможно, путаете «общий репозиторий», который является слоем для изоляции доступа к базам данных, с «репозиторием» в контексте вопроса ОП. Общий репозиторий в мире Symfony / Doctrine - это на самом деле ORM, а не рассматриваемый Entity Repositories.
  • 0
    Можете ли вы рассказать, что такое «универсальный репозиторий»? Мой ответ был направлен непосредственно на шаблон репозитория ORM доктрины, о котором говорил ОП
Показать ещё 1 комментарий
1

Хорошо, как вы получаете свой репозиторий, когда не используете entityManager? В конце концов, объекты не будут сохранены магически без подключения к базе данных, поэтому ваша служба должна каким-то образом знать о каком-либо соединении.

Я не знаю о SOA-сервисах, но в моих глазах это не имеет никакого значения, если вы используете $_em->getRepository()->save($entity) или $_em->persist($entity). С другой стороны, если вы используете флеш в своем репозитории, вы можете получить больше запросов, чем нужно, поскольку ваш репозиторий теперь знает о бизнес-логике.

Я думаю, что есть способ сделать это "путь SOA", но я предполагаю, что он не сохраняет сущности в репозитории.

  • 0
    Очень хороший момент по проблеме flush() . Возможно, флеш-парам для многословия?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню