简体   繁体   中英

Laravel Repository pattern

I read some articles about repository pattern and I want to know the reason why the constructor is needed when I can directly call the Model and return the data? I also think that Book::all(); is less code than $this->model->all() . Is it just a good practice or it has some purpose?

class BookRepository implements RepositoryInterface {

    private $model;

    public function __construct(Book $model)
    {
        $this->model = $model;
    }

    public function index()
    {
        return $this->model->all();
    }
}

and

class BookRepository implements RepositoryInterface {

    public function index()
    {
        return Book::all();
    }
}

The primary reason is Inversion of Control, basically letting your application determine what should be provided to fulfill that dependency. The reason this is important is, in the event you decide to refactor that code, you can simply tell Laravel to load a different implementation. No code need be altered in the Repository itself.

This however leads into the idea of not using classes directly, and using interfaces instead to declare your dependancies. That way any implementation can be swapped out and your code remains readable.

class BookRepository {

    public function __construct(BookInterface $book)
    {
        $this->book = $book;
    }

}

Now your Repository doesn't really care about the actual class, just that it implements the book interface which enforces a specific set of methods be defined. An example of the benefit is if you're using, say, MySQL as a database for your Book but switch to Postgres you may need to significantly change the underlying code but want to keep both implementations for legacy reasons. You can easily tell Laravel to load your standard Book class, or your new PostgresBook class because both still implement the BookInterface .

Your Repository doesn't need to change at all. Just add a bind and you're good.

Another more direct example is if you decided you wanted to switch from Eloquent to ActiveRecord.

Both will work but if for any reason you want to change the model class [Book] with any other model for example [MyBook] so in this case, you will change only the constructor parameter, not all the functions which use [Book]

public function __construct(MyBook $model)
{
    $this->model = $model;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM