Здравствуйте.
У меня в системе есть примерно вот такая структура:
shop/
--entity/
------Product.php
------ProductType.php
------Category.php
--repository/
------ProductRepository.php
------CategoryRepository.php
------ProductTypeRepository.php
.... и еще....
interface CategoryRepositoryInterface
{
public function findOne($id): CategoryInterface;
public function findAll(): array;
public function save(CategoryInterface $category);
public function remove(CategoryInterface $category);
}
interface ProductRepository
{
// .... все тоже самое, что и у CategoryRepositoryInterface
}
Product состоит из двух дополнительных частей (сильно упрощено, сущность с товаром довольно толстая):
interface Product
{
public function addCategory(CategoryInterface $category);
public function setProductType(ProductTypeInterface $productTypeInterface);
}
И тут возникает несколько проблем.
Первое, в ProductRepository нужно собрать из всех других репозиториев и вернуть через findOne() товар со всеми зависимостями (тип товара, категория, изображения, лицензии и прочее). Получается, что ProductRepository зависит от других репозиториев (Category, ProductType, Image, File....).
При удалении категории через $categoryRepository->remove() удаляются и товары (там бизнес логика на удаление завязана). Получается ад, репозиторий с категориями зависит от товара. А репозиторий с товарами зависит от репозитория с категориями и еще от нескольких других репозиториев. И тут у меня наступил dependency-hell.
В клиентском коде все должно быть просто:
$productRepository->findOne(100); // вжух и мы получили товар со всеми зависимостями и ИД 100.
Теперь главный вопрос - как собирать товар (или другую сущность) из разных кусков?
Сейчас я вызываю в методе findOne() репозитория соответствующие методы репозиториев других частей. Чувствую, что это неправильно, но как быть? Какие у вас практики, когда сущность собирается из разных кусков?
Как обрабатывать метод $productRepository->save($product), если разные куски товара сохраняются по-разному. Я сейчас прямо из метода save() дергаю отдельные репозитории в транзакции и сохраняю их. Правильно ли это?
Как быть с масштабированием, если в будущем появится еще что-то?