Почему я должен использовать черты и услуги в Laravel? - PullRequest
0 голосов
/ 12 декабря 2018

У меня простой вопрос, на который я изо всех сил стараюсь ответить, и надеюсь, ребята, вы можете мне помочь.Поэтому я разрабатываю приложение на Laravel.Я хотел, чтобы контроллеры были понятны, поэтому у меня есть сложные запросы внутри самих классов Model (я не хочу использовать репозитории).Если мне нужна функциональность, которая будет использоваться во многих моделях, я помещаю эту функциональность в черты характера и использую ее по мере необходимости.Итак, вот мой вопрос. Нужны ли вообще классы обслуживания?Разве черт недостаточно?

1 Ответ

0 голосов
/ 12 декабря 2018

Допустим, у вас есть метод в черте, который требует модель Cat и модель Dog.Каждый раз, когда вы используете эту черту, вам нужно передать экземпляр Cat и экземпляр Dog, чтобы он выполнял свою работу.

В конце концов это утомителен.И что произойдет, если вы в конечном итоге добавите особенность, а для этой черты теперь требуется модель Bird?Теперь у вас есть много кода, который нужно изменить, чтобы начать передавать Bird методу в признаке каждый раз, когда вы захотите его использовать.

Здесь класс обслуживания становится очень удобным.В конструкторе класса обслуживания вы можете вставить модель User, Permission и Role следующим образом ...

public function __construct(Cat $cat, Dog $dog, Bird $bird)
{
    $this->cat = $cat;
    $this->dog = $dog;
    $this->bird = $bird;
}

Затем вы можете добавить в свое приложение поставщика услуг, который инструктируетLaravel, как создать этот класс обслуживания, передав соответствующие модели.Оттуда вы можете автоматически внедрить эту услугу в ваши контроллеры, если считаете нужным, где в данный момент вы просто используете для этого черту.

Это означает, что если вам когда-либо понадобилось добавить зависимость, вам нужно толькообновить один, возможно два файла.Сам класс обслуживания для добавления дополнительных элементов в конструктор и, возможно, поставщика услуг.Все контроллеры, которые используют это, не должны обновляться для передачи этих дополнительных элементов конструктору, поскольку он обрабатывается Laravel (более подходящим образом - контейнер IoC).

Это также чрезвычайно полезно для тестирования.При внедрении зависимостей в класс проще просто настроить среду тестирования для имитации этих зависимостей, чем пытаться создавать насмешки на лету для передачи в методы trait.Также сложнее протестировать черту, поскольку что-то нужно use для этой черты, чтобы протестировать методы черты.

// we can use a service provider to tell laravel how to create this service (https://laravel.com/docs/5.7/providers)
class PetService
{
    protected $cat;
    protected $dog;
    protected $bird;

    public function __construct(Cat $cat, Dog $dog, Bird $bird)
    {
        $this->cat = $cat;
        $this->dog = $dog;
        $this->bird = $bird;
    }

    public function doStuff()
    {
        //  does things with $this->cat, $this->dog, $this->bird
    }
}


class PetController
{
    // use PetTrait;

    protected $petService;

    // laravel will automatically create the PetService for us and pass it into the constructor when building this controller (https://laravel.com/docs/5.7/container)
    public function __construct(PetService $petService) 
    {
        $this->petService = $petService;
    }

    public function someControllerMethod()
    {
        // $this->doStuff(new Cat, new Dog, new Bird); // In order to modify this method, we need to update each time it's used.
        $this->petService->doStuff(); // We don't need to worry about passing in arguments since it's handled by the service container when constructing the pet service and can make changes without updating each controller that uses it.
    }
}

И чтобы перейти к деталям, что произойдет, если вы решите Bird теперь для правильной работы требуется экземпляр Chicken, Turkey, Dodo.Теперь вам нужно снова пройтись по всем признакам, использующим Bird, и обновить каждый из них, чтобы передать экземпляр каждой из его зависимостей.

Вот почему выгодно использовать контейнер услуг и поставщиков для планирования ипостроить ваши зависимости ваших классов обслуживания.Это значительно повышает удобство сопровождения вашего приложения.Это было бы наиболее полезным в очень большом и сложном приложении.

Однако, если ваше приложение довольно простое, оно может быть не таким полезным и, возможно, даже добавить ненужную сложность, и черты могут фактически быть лучше использовать в этой точке, если они имеют больше смысла для вас.Нехорошо, чтобы ваше приложение было гибким при использовании сервисов, когда это не нужно.

...