如何在 Laravel 中使用 PHP 的裝飾器模式?下面本篇文章就來給大家介紹一下Laravel中使用PHP裝飾器模式的方法,希望對大家有所幫助!
Laravel 9 保姆級(jí)視頻教程,想學(xué)不會(huì)都難!進(jìn)入學(xué)習(xí)
設(shè)計(jì)模式對每個(gè)開發(fā)人員都很重要。它解決了您構(gòu)建的每個(gè)項(xiàng)目中非常常見的問題。
裝飾器模式定義:
它可以幫助您在一個(gè)對象上添加額外的行為,而又不影響同一類中的其他對象。
維基百科:
裝飾器模式是一種設(shè)計(jì)模式,它允許動(dòng)態(tài)地將行為添加到單個(gè)對象,而不會(huì)影響同一類中其他對象的行為
問題
假設(shè)我們有一個(gè)Post模型
class Post extends Model { public function scopePublished($query) { return $query->where('published_at', '<=', 'NOW()'); } }
在我們的PostsController中,我們有如下的index方法
class PostsController extends Controller { public function index() { $posts = Post::published()->get(); return $posts; } }
為了緩存帖子并避免每次我們需要列出帖子時(shí)都查詢數(shù)據(jù)庫,我們可以執(zhí)行以下操作
class PostsController extends Controller { public function index() { $minutes = 1440; # 1 day $posts = Cache::remember('posts', $minutes, function () { return Post::published()->get(); }); return $posts; } }
現(xiàn)在,我們將帖子緩存1天。但看看代碼,控制器了解了太多。它知道我們緩存了多少天,它自己緩存了對象。
同樣,假設(shè)您正在為HomePageController的Tag,Category,Archives實(shí)現(xiàn)相同的功能。閱讀和維護(hù)的代碼太多了。
倉庫模式
在大多數(shù)情況下,倉庫模式是連接到裝飾器模式。
首先,讓我們使用倉庫模式分離獲取帖子的方式,創(chuàng)建具有以下內(nèi)容的app/Repositories/Posts/PostsRepositoryInterface.php
namespace AppRepositoriesPosts; interface PostsRepositoryInterface { public function get(); public function find(int $id); }
在同個(gè)目錄下創(chuàng)建具有下面內(nèi)容的 PostsRepository
namespace AppRepositoriesPosts; use AppPost; class PostsRepository implements PostsRepositoryInterface { protected $model; public function __construct(Post $model) { $this->model = $model; } public function get() { return $this->model->published()->get(); } public function find(int $id) { return $this->model->published()->find($id); } }
回到PostsController并將更改應(yīng)用為
namespace AppHttpControllers; use AppRepositoriesPostsPostsRepositoryInterface; use IlluminateHttpRequest; class PostsController extends Controller { public function index(PostsRepositoryInterface $postsRepo) { return $postsRepo->get(); } }
控制器變得健康,知道足夠的細(xì)節(jié)來完成工作。
在這里,我們依靠 Laravel 的 IOC 注入 Posts 接口的具體對象來獲取我們的帖子
我們需要做的就是告訴Laravel的IOC使用接口時(shí)要?jiǎng)?chuàng)建哪個(gè)類。
在你的 app/Providers/AppServiceProvider.php
添加綁定方法
namespace AppProviders; use AppRepositoriesPostsPostsRepositoryInterface; use AppRepositoriesPostsPostsRepository; use IlluminateSupportServiceProvider; class AppServiceProvider extends ServiceProvider { public function register() { $this->app->bind(PostsRepositoryInterface::class,PostsRepository::class); } }
現(xiàn)在無論何時(shí)我們注入PostsRepositoryInterface
Laravel 都會(huì)創(chuàng)建 PostsRepository
的實(shí)例并將其返回。
通過裝飾器實(shí)現(xiàn)緩存
我們在一開始就說過,裝飾器模式允許將行為添加到單個(gè)對象,而不會(huì)影響同一類中的其他對象。
在這里緩存是行為,對象/類是 PostsRepository
。
讓我們在 app/Repositories/Posts/PostsCacheRepository.php
中創(chuàng)建具有以下內(nèi)容的PostsCacheRepository
namespace AppRepositoriesPosts; use AppPost; use IlluminateCacheCacheManager; class PostsCacheRepository implements PostsRepositoryInterface { protected $repo; protected $cache; const TTL = 1440; # 1 day public function __construct(CacheManager $cache, PostsRepository $repo) { $this->repo = $repo; $this->cache = $cache; } public function get() { return $this->cache->remember('posts', self::TTL, function () { return $this->repo->get(); }); } public function find(int $id) { return $this->cache->remember('posts.'.$id, self::TTL, function () { return $this->repo->find($id); }); } }
在這個(gè)類中,我們接受 Caching 對象和 PostsRepository 對象,然后使用類(裝飾器)將緩存行為添加到 PostsReposiory 實(shí)例。
我們可以使用相同的示例將HTTP請求發(fā)送到某些服務(wù),然后在失敗的情況下返回模型。我相信您會(huì)從該模式以及它是如何輕松添加行為中受益。
最后一件事是修改 AppServiceProvider 接口綁定以創(chuàng)建 PostsCacheRepository 實(shí)例而不是PostsRepository
namespace AppProviders; use AppRepositoriesPostsPostsRepositoryInterface; use AppRepositoriesPostsPostsCacheRepository; use IlluminateSupportServiceProvider; class AppServiceProvider extends ServiceProvider { public function register() { $this->app->bind(PostsRepositoryInterface::class,PostsCacheRepository::class); } }
現(xiàn)在再次檢查文件,您會(huì)發(fā)現(xiàn)它非常易于閱讀和維護(hù)。同樣,它也是可測試的,如果您決定在某個(gè)時(shí)候刪除緩存層。您只需在AppServiceProvider
中更改綁定即可。無需額外更改。
結(jié)論
- 我們學(xué)習(xí)了如何使用修飾器模式緩存模型
- 我們展示了倉庫模式如何連接到修飾器模式
- 依附注入和Laravel IOC如何使我們的生活變得輕松
- laravel組件功能強(qiáng)大
希望您喜歡閱讀本文。它向您展示了強(qiáng)大的設(shè)計(jì)模式,以及如何使您的項(xiàng)目易于維護(hù)和管理
原文地址:https://dev.to/ahmedash95/design-patterns-in-php-decorator-with-laravel-5hk6
【