Каково использование репозиториев и интерфейсов в Laravel?
После разработки нескольких проектов с использованием Codeigniter с 2 лет я уставился на изучение Laravel.
Я загрузил несколько проектов, чтобы узнать, как они закодированы. Как я понял, многие из них используют только модели, представления и контроллеры, которые аналогичны Codeigniter.
Но в одном проекте используются репозитории и интерфейсы. Трудно понять, что происходит в этом проекте. Итак, каково использование репозиториев и интерфейсов в Laravel? Когда я должен их использовать?
Ответы
Ответ 1
Я попытаюсь как можно яснее объяснить обе концепции.
Интерфейсы\контракты
В общем случае интерфейсы OOP используются для описания того, какие методы/функциональности класс, реализующий этот интерфейс, предлагает без заботы о фактической реализации.
Laravel использует Contracts
главным образом для разделения службы от фактической реализации. Чтобы быть более понятным, сделаем пример
<?php
namespace App\Orders;
class OrdersCache
{
protected $cache;
public function __construct(\SomePackage\Cache\Memcached $cache)
{
$this->cache = $cache;
}
public function find($id)
{
if ($this->cache->has($id)) {
//
}
}
}
Как вы можете видеть в этом классе, код тесно связан с реализацией кэша (т.е. \SomePackage\Cache\Memcached
), поэтому, если API этого класса Cache изменит наш код, он также должен быть соответствующим образом изменен. То же самое происходит, если мы хотим изменить реализацию Cache с другим (например, redis).
Вместо этого наш код может зависеть от интерфейса, который не зависит от реализации:
<?php
namespace App\Orders;
use Illuminate\Contracts\Cache\Repository as Cache;
class OrdersCache
{
public function __construct(Cache $cache)
{
$this->cache = $cache;
}
public function find($id)
{
if ($this->cache->has($id)) {
//
}
}
}
Теперь наш код не связан с какой-либо конкретной реализацией, потому что Cache
на самом деле является интерфейсом. Таким образом, в основном в нашем классе нам нужен экземпляр класса, который ведет себя так, как описано в интерфейсе Cache
, но нас действительно не интересует, как он работает внутри. Если мы хотим изменить реализацию кэша, мы могли бы написать класс, который реализует интерфейс Cache
без изменения какой-либо строки кода в нашем классе OrdersCache
. Выполнение этого кода легче понять и поддерживать, а ваши пакеты намного более многоразового использования. Подробнее см. Раздел Loose Coupling в документации Laravel.
Интерфейсы и контейнер обслуживания
Одной из основных особенностей Laravel является его контейнер сервисов, он используется для управления зависимостями и выполнения инъекции зависимостей. Пожалуйста, ознакомьтесь с Service Container из документации Laravel.
Injection Dependency широко используется Laravel для привязки интерфейсов к реализации. Приведем пример:
$app->bind('App\Contracts\EventPusher', 'App\Services\RedisEventPusher');
И пусть наш класс будет
<?php
namespace App\Http\Controllers;
use App\Contracts\EventPusher;
class EventsController extends Controller
{
protected $pusher;
public function __construct(EventPusher $pusher)
{
$this->pusher = $pusher;
}
}
Не объявляя ничего другого, мы в основном говорим каждый раз, когда кому-то нужен экземпляр EventPusher
, пожалуйста, Laravel, укажите экземпляр класса RedisEventPusher
. В этом случае каждый раз, когда ваш контроллер создается, Laravel передает экземпляр RedisEventPusher
на ваш контроллер, не указав ничего другого.
Вы можете вникать в это, посмотрев раздел Binding Interfaces to Implementation в документации Laravel.
Хранилища
Репозитории - это концепция, применимая к шаблону MVC независимо от любой конкретной структуры. Обычно у вас есть модель, которая является уровнем данных (например, напрямую взаимодействует с базой данных), ваш контроллер, который обрабатывает логику доступа на уровне данных и ваш вид, который показывает данные, предоставленные контроллером.
Репозитории могут быть определены следующим образом:
Проще говоря, шаблон репозитория - это своего рода контейнер, в котором хранится логика доступа к данным. Он скрывает детали логики доступа к данным из бизнес-логики. Другими словами, мы разрешаем бизнес-логике получать доступ к объекту данных без знания базовой архитектуры доступа к данным.
Сорвали: https://bosnadev.com/2015/03/07/using-repository-pattern-in-laravel-5
Чтобы узнать, как использовать их в Laravel, пожалуйста, взгляните на эту отличную статью.
Что все, я надеюсь, это поможет прояснить ваш разум.
Ответ 2
Интерфейсы - это то, что должен вызвать любой класс реализации.
interface CanFlyInterface
{
public function fly();
}
Подумайте об этом, как о программировании, не беспокоясь о логике.
if ($object instanceof CanFlyInterface) {
$obj->fly();
}
Теперь мы могли бы пройти объект Bird или объект самолета! PHP НЕ УХОДИТ, если он реализует интерфейс!
class Bird implements CanFlyInterface
{
public function fly()
{
return 'flap flap!';
}
}
class Aeroplane implements CanFlyInterface
{
public function fly()
{
return 'roar! whoosh!';
}
}
Другой вопрос, что такое класс репозитория. Это просто класс, который хранит все ваши запросы к БД в одном месте. Проверьте этот интерфейс в качестве примера:
interface RepositoryInterface
{
public function insert(array $data);
public function update(array $data);
public function findById($id);
public function deleteById($id);
}
Надеюсь, это должно очистить вас! Удачи всем вашим PHP-кодировкам: -D
Ответ 3
Начнем с более простого интерфейса:
Обычно вы используете интерфейсы для реализации классов с помощью необходимых методов:
http://php.net/manual/en/language.oop5.interfaces.php
Laravel Contracts - это набор интерфейсов, которые определяют основные сервисы, предоставляемые инфраструктурой. Например, контракт Illuminate\Contracts\Queue\Queue определяет методы, необходимые для задания очередей, в то время как контракт Illuminate\Contracts\Mail\Mailer определяет методы, необходимые для отправки электронной почты. https://laravel.com/docs/5.4/contracts#introduction
Когда Laravel работает, он может проверить, реализует ли класс специальный интерфейс:
if ($cls instanceof IInterface) {
$cls->interfaceFunction();
}
Так как Laravel может работать с очередями, он проверяет, должно ли событие быть поставлено в очередь или нет, путем проверки выходного интерфейса.
Чтобы сообщить Laravel, что данное событие должно транслироваться, реализуйте интерфейс Illuminate\Contracts\Broadcasting\ShouldBroadcast в классе событий. https://laravel.com/docs/5.4/broadcasting#defining-broadcast-events
Repository:
Я так не нашел об этом:
В нашем хранилище не должно быть так много знаний о том, кто предоставляет им данные или как они его предоставляют. https://laravel.com/docs/5.4/contracts#loose-coupling
Но я нашел другую информацию на веб-странице:
a Репозиторий будет подключать Фабрики со шлюзами https://code.tutsplus.com/tutorials/the-repository-design-pattern--net-35804
Ссылка даст вам дополнительную информацию о деталях.
Надеюсь, что смогу вам помочь:)
Ответ 4
Прежде всего, репозитории и интерфейсы не являются специфичными для Laravel, а являются стандартами общего кодирования на большинстве языков.
Ниже видео Laracasts будет полезно понять основы, если вы не против потратить несколько долларов.
https://laracasts.com/lessons/repositories-and-inheritance
https://laracasts.com/series/object-oriented-bootcamp-in-php
Ответ 5
Прежде всего, использование репозитория и интерфейса в более крупном приложении не только является бенефициаром в Laravel, но и во всех технологиях для стандартизации кодирования, а также для разделения проблем.
В соответствии с Microsoft (я нашел лучшее объяснение здесь)
Зачем использовать репозиторий:
Используйте репозиторий для разделения логики, которая извлекает данные и сопоставляет его с моделью сущности из бизнес-логики, которая действует на модель. Бизнес-логика должна быть агностикой для типа данных, которые содержит слой источника данных. Репозиторий обеспечивает посредничество между уровень источника данных и бизнес-уровни приложения. Это запрашивает источник данных для данных, отображает данные из данных источника для субъекта бизнеса и сохраняет изменения в бизнесе объект к источнику данных.
Репозиторий разделяет бизнес-логику от взаимодействия с базовым источником данных или веб-службой. Разделение между данными и бизнес-уровнями имеет три преимущества: Он централизует логику логики данных или логику доступа к веб-сервисам. Это обеспечивает точка замены для единичных тестов. Он обеспечивает гибкое архитектуры, которая может быть адаптирована как общий дизайн приложение развивается. Существует два способа, с помощью которых репозиторий может запрашивать хозяйствующих субъектов. Он может отправлять объект запроса на клиентский бизнес-логики или он может использовать методы, которые определяют бизнес критерии. В последнем случае репозиторий формирует запрос на клиент. Репозиторий возвращает соответствующий набор объектов которые удовлетворяют запросу.
Для интерфейса у вас есть много ответов выше, надеюсь, что вы понимаете.