Laravel 9 保姆級視訊教學,想學不會都難!進入學習
設計模式對每個開發人員都很重要。它解決了您構建的每個專案中非常常見的問題。
它可以幫助您在一個物件上新增額外的行為,而又不影響同一類中的其他物件。
裝飾器模式是一種設計模式,它允許動態地將行為新增到單個物件,而不會影響同一類中其他物件的行為
假設我們有一個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; } }
為了快取貼文並避免每次我們需要列出貼文時都查詢資料庫,我們可以執行以下操作
class PostsController extends Controller { public function index() { $minutes = 1440; # 1 day $posts = Cache::remember('posts', $minutes, function () { return Post::published()->get(); }); return $posts; } }
現在,我們將貼文快取1天。但看看程式碼,控制器瞭解了太多。它知道我們快取了多少天,它自己快取了物件。
同樣,假設您正在為HomePageController的Tag,Category,Archives實現相同的功能。閱讀和維護的程式碼太多了。
在大多數情況下,倉庫模式是連線到裝飾器模式。
首先,讓我們使用倉庫模式分離獲取貼文的方式,建立具有以下內容的app/Repositories/Posts/PostsRepositoryInterface.php
namespace App\Repositories\Posts; interface PostsRepositoryInterface { public function get(); public function find(int $id); }
在同個目錄下建立具有下面內容的 PostsRepository
namespace App\Repositories\Posts; use App\Post; 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並將更改應用為
namespace App\Http\Controllers; use App\Repositories\Posts\PostsRepositoryInterface; use Illuminate\Http\Request; class PostsController extends Controller { public function index(PostsRepositoryInterface $postsRepo) { return $postsRepo->get(); } }
控制器變得健康,知道足夠的細節來完成工作。
在這裡,我們依靠 Laravel 的 IOC 注入 Posts 介面的具體物件來獲取我們的貼文
我們需要做的就是告訴Laravel的IOC使用介面時要建立哪個類。
在你的 app/Providers/AppServiceProvider.php
新增繫結方法
namespace App\Providers; use App\Repositories\Posts\PostsRepositoryInterface; use App\Repositories\Posts\PostsRepository; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider { public function register() { $this->app->bind(PostsRepositoryInterface::class,PostsRepository::class); } }
現在無論何時我們注入PostsRepositoryInterface
Laravel 都會建立 PostsRepository
的範例並將其返回。
我們在一開始就說過,裝飾器模式允許將行為新增到單個物件,而不會影響同一類中的其他物件。
在這裡快取是行為,物件/類是 PostsRepository
。
讓我們在 app/Repositories/Posts/PostsCacheRepository.php
中建立具有以下內容的PostsCacheRepository
namespace App\Repositories\Posts; use App\Post; use Illuminate\Cache\CacheManager; 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); }); } }
在這個類中,我們接受 Caching 物件和 PostsRepository 物件,然後使用類(裝飾器)將快取行為新增到 PostsReposiory 範例。
我們可以使用相同的範例將HTTP請求傳送到某些服務,然後在失敗的情況下返回模型。我相信您會從該模式以及它是如何輕鬆新增行為中受益。
最後一件事是修改 AppServiceProvider 介面繫結以建立 PostsCacheRepository 範例而不是PostsRepository
namespace App\Providers; use App\Repositories\Posts\PostsRepositoryInterface; use App\Repositories\Posts\PostsCacheRepository; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider { public function register() { $this->app->bind(PostsRepositoryInterface::class,PostsCacheRepository::class); } }
現在再次檢查檔案,您會發現它非常易於閱讀和維護。同樣,它也是可測試的,如果您決定在某個時候刪除快取層。您只需在AppServiceProvider
中更改繫結即可。無需額外更改。
希望您喜歡閱讀本文。它向您展示了強大的設計模式,以及如何使您的專案易於維護和管理
原文地址:https://dev.to/ahmedash95/design-patterns-in-php-decorator-with-laravel-5hk6
【相關推薦:】
以上就是聊聊Laravel中怎麼使用 PHP 的裝飾器模式的詳細內容,更多請關注TW511.COM其它相關文章!