3

在閱讀了其他幾個問題後,看起來實體類使用Repository並不可取。所以考慮到這些資料庫: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是不是我們可以稱之爲一個「最佳實踐」,以及...

任何評論歡迎!

回答

3

如果您需要對餐廳進行評論,您的餐廳資料庫應該(也可以選擇)將其與餐廳進行檢索。這些將作爲評論集合與每個餐廳的其他數據一起存儲在類實例中。這將允許您構建更高效的查詢,以便一次性獲取所有數據並填充所需的對象。設計模式被稱爲aggregate root

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) { 
     ... 
    } 
} 
?> 
+0

感謝您的回答。其實,餐廳和評論都是聚合的根源(評論有一個餐廳和一個用戶,並擁有自己的存儲庫)。評論可以在餐廳外創建,因此根據我的理解,這不是餐館聚合的一部分。因此,餐廳的*評論集合*仍應由餐廳存儲庫填充? – Benjamin

+0

我終於意識到,我不需要每家餐廳的所有評論,但只是他們的總結。因此,我在餐廳實體中添加了評論統計信息(評論數量,平均評分),並且不再需要訪問ReviewRepository。如果我需要這樣做,我只需引入一個包含餐廳及其評論的值對象,並將其傳遞給視圖。 – Benjamin