stalxed
Новичок
Сейчас писал код для очень простой задачи.
Количество граблей такая простая задача собрала очень уж много.
Есть сущность Order. Обычный заказ клиента. Он не важен.
Есть сущность BadOrderEntry, простая сущность, в которой есть следующие поля:
- id
- order - unidirectional one-to-one relationship with Order
- createdAt - дата создания
Есть репозиторий BadOrderEntryRepository
Фабрика BadOrderEntryFactory, создающая BadOrderEntry
Необходимо сделать простой список BadOrderList:
При повторном добавление Order в список нужно просто ничего не делать.
Есть несколько решений этой задачи:
Создавать транзакцию может:
(т.е. где разместить функцию вида:
)
Количество граблей такая простая задача собрала очень уж много.
Есть сущность Order. Обычный заказ клиента. Он не важен.
Есть сущность BadOrderEntry, простая сущность, в которой есть следующие поля:
- id
- order - unidirectional one-to-one relationship with Order
- createdAt - дата создания
Есть репозиторий BadOrderEntryRepository
Фабрика BadOrderEntryFactory, создающая BadOrderEntry
Необходимо сделать простой список BadOrderList:
Код:
<?php
class BadOrderList
{
public function has(Order $order);
public function add(Order $order);
public function remove(Order $order);
}
Есть несколько решений этой задачи:
- Отлавливать Exception по коду mysql и ругани на уникальный индекс.Минус: рвётся соединение с доктриной и его необходимо восстанавливать.
- Самому реализовывать update if exists, так как php doctrine 2 его не поддерживает.
- Выполнять поиск записи, и если она не существует, то выполнять добавление. НО! Это нужно обворачивать в транзакцию. Минус: производительность. Но меня этот способ устраивает больше всех.
- Доступ к фабрике BadOrderEntryFactory
- Доступ к репозиторию BadOrderEntryRepository (получаю как описано тут)
- Доступ к \Doctrine\Common\Persistence\ObjectManager (получаю как описано тут)
- Где и как создавать транзакцию?
- Кто должен отвечать за сохранение/редактирование/удаление?
Создавать транзакцию может:
- Репозиторий BadOrderEntryRepository выполняет сам всю транзакцию целиком, включая бизнес логику.
- Репозиторий BadOrderEntryRepository, в нём функция transactional, которая принимает callback и выполняет транзакцию через вызов $em->transactional($callback).
- Некий централизованный класс TransactionMaker, в нём функция transactional, которая принимает callback и выполняет транзакцию через вызов $em->transactional($callback).
- Создать BadOrderEntryManager, который выполняет сам всю транзакцию целиком, включая бизнес логику. BadOrderList просто вызывает его.
- BadOrderList выполняет сам всю транзакцию целиком, включая бизнес логику.
- Другие варианты?
(т.е. где разместить функцию вида:
PHP:
public function save(BadOrderEntry $entry, $andFlush = true)
{
$this->entityManager->persist($entry);
if ($andFlush) {
$this->entityManager->flush();
}
}
- в репозитории
- создать BadOrderEntryManager и в нём
- в BadOrderList
- Фабрика BadOrderEntryFactory для создания BadOrderEntry
- Репозиторий BadOrderEntryRepository только для операций поиска.
- Менеджер BadOrderEntryManager для управления операциями сохранения/редактирования/удаления.
- Некий централизованный класс TransactionMaker для транзакций.
- Всё это инжектится в BadOrderList, который и управляет ими, представляя клиентскому коду всего 3 метода has, add, remove.
- Не объединить ли пункты 2 и 3(т.е. методы менеджера перенести в репозиторий).
- Очень сильно сомневаюсь в пункте 4. Не знаю, куда вообще пристроить транзакции.