最近我開始研究Laravel 4
及其功能。我想實現Repository模式以在那裏移動模型邏輯。在這一點上,我面臨着一些如何組織它的不便或誤解。一般問題我有這樣的事情:是否有可能實現和應用這種模式在Laravel
沒有頭痛,並且它是否值得?使用Laravel實現庫模式
這個問題會被分成幾個部分,這引起了我的困惑。
1)Laravel提供了將模型綁定爲控制器參數的方便方式,例如,我做這種方式:
// routes.php
Route::bind('article', function($slug)
{
return Article::where('slug', $slug)->first();
});
Route::get('articles/{article}', '[email protected]');
// controllers/ArticlesController.php
class ArticlesController extends BaseController {
public function getArticle(Article $article)
{
return View::make('article.show', compact('article'));
}
}
如果我想使用Repository
模式,那麼我不能使用這種方法,因爲在這種情況下,控制器將清楚地瞭解車型Article
存在? 無論將是正確的重新寫該示例中使用Repository模式這樣:
// routes.php
Route::get('articles/{slug}', '[email protected]');
// controllers/ArticlesController.php
class ArticlesController extends BaseController {
private $article;
public function __construct(ArticleRepository $article) {
$this->article = $article;
}
public function getArticle($slug)
{
$article = $this->article->findBySlug($slug);
return View::make('article.show', compact('article'));
}
}
2)假設,我的代碼與上面使用的Repository
是正確的。現在,我想在每次顯示文章視圖計數器時增加文章視圖,但是,我想在Event
中進行此處理。也就是說,代碼如下:
// routes.php
Route::get('articles/{slug}', '[email protected]');
// controllers/ArticlesController.php
class ArticlesController extends BaseController {
private $article;
public function __construct(ArticleRepository $article) {
$this->article = $article;
}
public function getArticle($slug)
{
$article = $this->article->findBySlug($slug);
Events::fire('article.shown');
return View::make('articles.single', compact('article'));
}
}
// some event subscriber
class ArticleSubscriber {
public function onShown()
{
// why implementation is missed described bellow
}
public function subscribe($events)
{
$events->listen('article.shown', '[email protected]');
}
}
在這一點上我再次對如何實現事件處理感到困惑。我無法直接將$article
模型傳遞給事件,因爲它再次違反了OOP的原則,我的訂閱者將知道文章模型的存在。所以,我不能這樣做:
// controllers/ArticlesController.php
...
\Events::fire('article.shown', $article);
...
// some event subscriber
...
public function onShown(Article $article)
{
$article->increment('views');
}
...
在另一方面,我沒有看到任何意義,引入subscriber
庫ArticleRepository
(或用戶的構造器注入的話),因爲首先我應該找一個文章,然後更新計數器,最終,我會得到額外的查詢(在構造函數之前,因爲我這樣做)到數據庫:
// controllers/ArticlesController.php
...
Events::fire('article.shown', $slug);
...
// some event subscriber
...
private $article;
public function __construct(ArticleRepository $articleRepository)
{
$this->article = $articleRepository;
}
public function onShown($slug)
{
$article = $this->articleRepository->findBySlug($slug);
$article->increment('views');
}
...
此外,處理的Event
後(即增加的觀看次數) ,控制器必須知道更新的模型,因爲在視圖中我想顯示更新的視圖計數器。事實證明,我仍然需要從Event
返回一個新的模型,但我不想Event
已成爲處理特定操作(爲此有存儲庫),並返回一些價值的常見方法。此外,您可能會注意到我的最後onShow()
方法再次違背Repository
模式的規則,但我不知道如何把這個邏輯到倉庫:
public function onShown($slug)
{
$article = $this->articleRepository->findBySlug($slug);
// INCORRECT! because the Event shouldn't know that the model is able to implement Eloquent
// $article->increment('views');
}
我可以以某種方式通過發現模型回到倉庫並增加她的櫃檯(這與Repository
模式的方法相矛盾嗎?)?事情是這樣的:
public function onShown($slug)
{
$article = $this->articleRepository->findBySlug($slug);
$this->articleRepository->updateViews($article);
}
// ArticleRepository.php
...
public function updateViews(Article $article) {
$article->increment('views');
}
...
結果,我會盡量制定所有更緊湊:
我不得不拒絕直接傳遞模型,由DI提供的控制器和其他設施如果我將使用
Repository
模式?是否可以使用存儲庫來存放模型的狀態,並通過它的實體之間(例如,從過濾器控制器從控制器到
Event
和背面)避免淫穢重複調用數據庫,是這方法將是正確的(模型持久性)?
這樣的事情,這些是我的問題。我想聽聽答案,想法和意見。也許,我應用模式的方法不正確?現在它比解決數據映射問題更令人頭疼。
此外,我讀過有關倉庫實現的一些文章:
- http://heera.it/laravel-repository-pattern#.VFaKu8lIRLe
- http://vegibit.com/laravel-repository-pattern
,但它並沒有解決我的誤解