DDD/MVC: как избежать попадания в репозиторий из представления?

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

class RestaurantRepository {
    public function findAll() { ... }
}

class ReviewRepository {
    public function findByRestaurant(Restaurant $restaurant) { ... }
}

Я не должен делать это в своем классе:

class Restaurant {
    public function getReviews() {
        // ...
        return $restaurantRepository->findByRestaurant($this);
    }
}

Но скажем, у меня есть этот контроллер, который выдает список ресторанов в представление:

class IndexController {
    public function indexAction() {
        $restaurants = $restaurantRepository->findAll();
        $this->view->restaurants = $restaurants;
    }
}

Что такое «хорошая практика» для получения отзывов о каждом ресторане в сценарии просмотра? Поэтому я не могу сделать это:

foreach ($this->restaurants as $restaurant) {
    $reviews = $restaurant->getReviews();
}

И я предполагаю, что внедрение ReviewRepository в представление - это не то, что мы можем назвать "лучшей практикой"...

Приветствуются любые комментарии!


person BenMorel    schedule 31.07.2011    source источник


Ответы (1)


Если вам нужны отзывы о ресторане, репозиторий вашего ресторана должен (возможно, необязательно) получить их вместе с рестораном. Они будут храниться в экземпляре класса как набор обзоров вместе с другими данными каждого ресторана. Это позволит вам построить более эффективный запрос, который будет получать все данные за один раз и заполнять нужные объекты. Шаблон проектирования называется агрегированный корень.

class RestaurantRepository {
    public function findAll($withReviews = 0) { ... }
}

class IndexController {
    public function indexAction() {
        $restaurants = $restaurantRepository->findAll(1);
        $this->view->restaurants = $restaurants;
    }
}

<?php
foreach ($this->restaurants as $restaurant) {
    foreach ($restaurant->reviews as $review) {
       ...
    }
}
?>
person tvanfosson    schedule 31.07.2011
comment
Спасибо за Ваш ответ. На самом деле, и Ресторан, и Обзор являются сводными корнями (у Обзора есть Ресторан и Пользователь, а также собственный Репозиторий). Обзор может быть создан вне ресторана, поэтому, насколько я понимаю, он не является частью совокупности ресторана. Следовательно, должен ли коллекция отзывов ресторана по-прежнему заполняться репозиторием ресторана? - person BenMorel; 01.08.2011
comment
В конце концов я понял, что мне нужны не все отзывы по каждому ресторану, а только их краткое изложение. Поэтому я поместил статистику отзывов (количество отзывов, средний рейтинг) в объект «Ресторан», и мне больше не нужно обращаться к ReviewRepository. И если бы мне нужно было это сделать, я бы просто ввел объект значения, который содержал бы ресторан вместе с его отзывами, и передал бы его в представление. - person BenMorel; 07.02.2013