Подтвердить что ты не робот

Каково использование репозиториев и интерфейсов в Laravel?

После разработки нескольких проектов с использованием Codeigniter с 2 лет я уставился на изучение Laravel.

Я загрузил несколько проектов, чтобы узнать, как они закодированы. Как я понял, многие из них используют только модели, представления и контроллеры, которые аналогичны Codeigniter.

Но в одном проекте используются репозитории и интерфейсы. Трудно понять, что происходит в этом проекте. Итак, каково использование репозиториев и интерфейсов в Laravel? Когда я должен их использовать?

4b9b3361

Ответ 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 (я нашел лучшее объяснение здесь)

Зачем использовать репозиторий:

Используйте репозиторий для разделения логики, которая извлекает данные и сопоставляет его с моделью сущности из бизнес-логики, которая действует на модель. Бизнес-логика должна быть агностикой для типа данных, которые содержит слой источника данных. Репозиторий обеспечивает посредничество между уровень источника данных и бизнес-уровни приложения. Это запрашивает источник данных для данных, отображает данные из данных источника для субъекта бизнеса и сохраняет изменения в бизнесе объект к источнику данных.
Репозиторий разделяет бизнес-логику от взаимодействия с базовым источником данных или веб-службой. Разделение между данными и бизнес-уровнями имеет три преимущества: Он централизует логику логики данных или логику доступа к веб-сервисам. Это обеспечивает точка замены для единичных тестов. Он обеспечивает гибкое архитектуры, которая может быть адаптирована как общий дизайн приложение развивается. Существует два способа, с помощью которых репозиторий может запрашивать хозяйствующих субъектов. Он может отправлять объект запроса на клиентский бизнес-логики или он может использовать методы, которые определяют бизнес критерии. В последнем случае репозиторий формирует запрос на клиент. Репозиторий возвращает соответствующий набор объектов которые удовлетворяют запросу.

Для интерфейса у вас есть много ответов выше, надеюсь, что вы понимаете.