Home  >  Article  >  PHP Framework  >  Let's talk about how to use PHP's decorator pattern in Laravel

Let's talk about how to use PHP's decorator pattern in Laravel

青灯夜游
青灯夜游forward
2022-09-20 11:12:352354browse

How to use PHP's decorator pattern in Laravel? The following article will introduce to you how to use the PHP decorator mode in Laravel. I hope it will be helpful to you!

Let's talk about how to use PHP's decorator pattern in Laravel

Design patterns are important for every developer. It solves very common problems in every project you build.

Decorator pattern definition:

It helps you add extra behavior on an object without affecting other objects in the same class other objects.

Wikipedia:

The decorator pattern is a design pattern that allows for dynamically adding behavior to a single object, Without affecting the behavior of other objects in the same class

Question

Suppose we have a Post model

class Post extends Model
{
    public function scopePublished($query) {
        return $query->where('published_at', '<=&#39;, &#39;NOW()&#39;);
    }
}

In our PostsController, we have the index method as follows

class PostsController extends Controller
{
    public function index() {
        $posts = Post::published()->get();
        return $posts;
    }
}

In order to cache the posts and avoid querying the database every time we need to list the posts, we can do the following

class PostsController extends Controller
{
    public function index() {
        $minutes = 1440; # 1 day
        $posts = Cache::remember('posts', $minutes, function () {
            return Post::published()->get();
        });
        return $posts;
    }
}

Now we cache posts for 1 day. But looking at the code, the controller knows too much. It knows how many days we have cached it, it caches the object itself.

Similarly, assume you are implementing the same functionality for Tag, Category, Archives of HomePageController. That's too much code to read and maintain.

Warehouse Pattern

In most cases, the warehouse pattern is connected to the decorator pattern.

First, let’s use the repository pattern to separate the way of getting posts, creating app/Repositories/Posts/PostsRepositoryInterface.php

namespace App\Repositories\Posts;

interface PostsRepositoryInterface 
{

    public function get();

    public function find(int $id);

}
# with the following content ##Create a

PostsRepository with the following content in the same directory

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);
    }

}
Go back to the PostsController and apply the changes to

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();
    }
}
The controller becomes healthy and knows enough Details get the job done.

Here, we rely on Laravel's IOC to inject the specific object of the Posts interface to get our posts

All we need to do is tell Laravel's IOC which class to create when using the interface.

In your

app/Providers/AppServiceProvider.php add binding method

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);
    }
}
Now whenever we inject

PostsRepositoryInterface Laravel will create# An instance of ##PostsRepository and returns it.

Caching through decoratorsWe said at the beginning that the decorator pattern allows adding behavior to a single object without Will affect other objects in the same class.

Here caching is the behavior and the object/class is the

PostsRepository

. Let’s create

PostsCacheRepository with the following content in

app/Repositories/Posts/PostsCacheRepository.php In this class, we Accepts a Caching object and a PostsRepository object, and then uses a class (decorator) to add caching behavior to the PostsRepository instance. We can use the same example to send an HTTP request to some service and then return the model in case of failure. I believe you will benefit from this pattern and how easy it is to add behavior.

The last thing is to modify the AppServiceProvider interface binding to create a PostsCacheRepository instance instead of a PostsRepository

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);
        });
    }
}
Now check the file again and you will see that it is very easy to read and maintain. Likewise, it's testable if you decide to remove the cache layer at some point. You just need to change the binding in

AppServiceProvider

. No additional changes are required.

Conclusion

We learned how to cache a model using the decorator patternWe showed how the warehouse pattern Connecting to the Decorator Pattern

    How Dependency Injection and Laravel IOC Make Our Life Easy
  • Laravel Components are Powerful
  • Hope you enjoyed reading this article. It shows you powerful design patterns and how to make your projects easy to maintain and manage
  • Original address: https://dev.to/ahmedash95/design-patterns-in-php- decorator-with-laravel-5hk6

[Related recommendations:
laravel video tutorial

]

The above is the detailed content of Let's talk about how to use PHP's decorator pattern in Laravel. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:learnku.com. If there is any infringement, please contact admin@php.cn delete