Gần đây tôi bắt đầu nghiên cứu Laravel 4
và khả năng của nó. Tôi muốn thực hiện mô hình Repository để di chuyển mô hình logic ở đó. Và tại thời điểm này tôi phải đối mặt với một số bất tiện hoặc sự hiểu lầm về cách tổ chức nó. Câu hỏi chung tôi đã đi một cái gì đó như thế này: là nó có thể thực hiện và áp dụng mô hình này trong Laravel
mà không đau đầu, và liệu nó có giá trị?Thực hiện mẫu lưu trữ với Laravel
Câu hỏi sẽ được chia thành nhiều phần, điều này gây ra sự nhầm lẫn của tôi.
1) Laravel cung cấp cách thuận tiện để liên kết mô hình dưới dạng thông số bộ điều khiển, ví dụ: tôi làm điều đó theo cách này:
// 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'));
}
}
Nếu tôi muốn sử dụng mô hình Repository
, sau đó tôi không thể sử dụng phương pháp này, vì trong trường hợp này bộ điều khiển sẽ rõ ràng nhận thức được sự tồn tại của mô hình Article
? Cho dù đó sẽ được chính xác để viết lại ví dụ này sử dụng mẫu Repository cách này:
// 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) Giả sử, mã của tôi ở trên với việc sử dụng các Repository
là đúng. Bây giờ tôi muốn tăng lượt xem bài viết truy cập mỗi lần nó sẽ được hiển thị, tuy nhiên, tôi muốn thực hiện việc xử lý này trong Event
. Tức là, mã như sau:
// 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]');
}
}
Tại thời điểm này tôi đã bối rối một lần nữa về cách triển khai xử lý sự kiện. Tôi không thể vượt qua mô hình $article
trực tiếp cho sự kiện, bởi vì, một lần nữa, nó vi phạm các nguyên tắc của OOP và người đăng ký của tôi sẽ biết về sự tồn tại của mô hình bài viết. Vì vậy, tôi không thể làm như vậy:
// controllers/ArticlesController.php
...
\Events::fire('article.shown', $article);
...
// some event subscriber
...
public function onShown(Article $article)
{
$article->increment('views');
}
...
Mặt khác tôi không thấy bất kỳ ý nghĩa để giới thiệu vào subscriber
kho ArticleRepository
(hoặc tiêm nó trong contructor của thuê bao), bởi vì lần đầu tiên tôi nên tìm một bài viết, và sau đó cập nhật bộ đếm, cuối cùng, tôi sẽ nhận được thêm truy vấn (gây ra trước đó trong constructor tôi làm như vậy) để cơ sở dữ liệu:
// 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');
}
...
Hơn nữa, sau khi Event
xử lý (xem ví dụ tăng đếm) , nó là cần thiết mà bộ điều khiển biết về mô hình cập nhật, bởi vì trong khung nhìn tôi muốn hiển thị các khung nhìn đã cập nhật quầy tính tiền. Nó chỉ ra rằng bằng cách nào đó tôi vẫn cần phải trả lại một mô hình mới từ Event
, nhưng tôi không muốn Event
đã trở thành một phương pháp phổ biến để xử lý một hành động cụ thể (cho điều này có kho) và trả về một số giá trị. Ngoài ra, bạn có thể nhận thấy rằng onShow()
phương pháp cuối cùng của tôi một lần nữa trái với các quy tắc của Repository
mẫu, nhưng tôi không hiểu làm thế nào để đưa logic này vào kho:
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');
}
Tôi có thể bằng cách nào đó vượt qua các mô hình tìm thấy trở lại kho lưu trữ và tăng truy cập của cô ấy (nó có mâu thuẫn với cách tiếp cận này để Repository
mẫu?)? Something như thế này:
public function onShown($slug)
{
$article = $this->articleRepository->findBySlug($slug);
$this->articleRepository->updateViews($article);
}
// ArticleRepository.php
...
public function updateViews(Article $article) {
$article->increment('views');
}
...
Kết quả là, tôi sẽ cố gắng để xây dựng tất cả nhỏ gọn hơn:
tôi sẽ phải từ chối để vượt qua mô hình trực tiếp để điều khiển và tiện nghi khác được cung cấp bởi DI , nếu tôi sẽ sử dụng mẫu
Repository
?Có thể sử dụng kho lưu trữ để giữ trạng thái của mô hình và vượt qua giữa các thực thể (ví dụ, từ bộ lọc đến bộ điều khiển từ bộ điều khiển đến
Event
và ngược lại) tránh các cuộc gọi lặp lại tục tĩu đến db và cách tiếp cận sẽ đúng (mô hình kiên trì)?
Những thứ như vậy, đây là những câu hỏi của tôi. Tôi muốn nghe câu trả lời, suy nghĩ, bình luận. Có lẽ, tôi tiếp cận không chính xác để áp dụng các mô hình? Bây giờ nó gây ra nhiều đau đầu hơn là giải quyết vấn đề lập bản đồ dữ liệu.
Ngoài ra tôi đã đọc một số bài viết về thực hiện Repository:
- http://heera.it/laravel-repository-pattern#.VFaKu8lIRLe
- http://vegibit.com/laravel-repository-pattern
nhưng nó không giải quyết hiểu lầm tôi