Паттерн «Сервисный слой» в Laravel

Паттерн Сервисный слой в Ларавел

Сервисный слой (Service layer) — это шаблон проектирования, который поможет вам абстрагировать логику от логики предметной области (domain logic), при необходимости использования разных интерфейсов. На самом деле вы делегируете логику приложения общему сервису (сервисному слою) и обслуживаете только один класс. К тому же это хороший способ почистить ваши контроллеры и содержать их в читабельном виде.

Суть в том, что при росте вашего приложения, вы спасете сами себя от повторения кусков кода, так как будете сосредоточены только на одном классе Service, без необходимости обновлять все контроллеры.

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

Представьте себе приложение, в котором вы хотите предложить своим пользователям возможность создания купона для своих клиентов.

Контроллер API

Если вы не отделите логику, то можете попасть в ловушку, когда ваши контроллеры быстро станут громоздкими и нечитаемыми. Вот пример того, что вы могли бы сделать:

public function store(CreateCoupon $request)
{
    $validator = $this->validate($request->all(), [...]);

    \App\Coupon::create([

        'code' => $request->get('code'),
        'amount' => $request->get('amount'),
        'max_redemptions' => $request->get('max_redemptions')

    ]);

    return redirect('coupons')->withSucces($message);
}

А сейчас вашему боссу потребовалась реферальная программа. Ну, вы и копируете/вставляете опять эту функцию, вносите некоторые изменения и запускаете в продакшн. Вы будете повторять этот процесс снова и снова, пока вам не понадобится добавить столбец в таблицу купонов: придется обновлять все свои правила валидации, исправлять все места, где вы использовали этот фрагмент кода и т.д.

Делайте ваш контроллер читабельным и понятным

Первое, что нужно сделать, это переместить правила проверки в класс валидации. Это не часть Сервисного слоя, но раз уж Laravel предоставляем нам удобный способ сделать это. Теперь, когда вы создали класс запроса, вы можете добавить его через параметр $request.

Вторая часть заключается в создании класса Service. Сделайте в папке app папку Services, а в ней файл с классом CreateCouponService. Добавьте метод make() и вставьте код для создания новой сущности:

public function make(CreateCoupon $request)
{

   $coupon = \App\Coupon::create([
     'code' => $request->get('code'),
     'amount' => $request->get('amount'),
     'max_redemptions' => $request->get('max_redemptions')
   ]);

   return $coupon; 

}

Теперь вы можете отредактировать CouponController и внедрить ваш сервис через конструктор, чтобы вы могли использовать его как свойство.

Ваш метод в контроллере должен выглядеть следующим образом:

public function store(CreateCoupon $request)
{
    $this->createCouponService->make($request);

    return back()->with(['success' => 'Congratulations!']);
}

Представьте теперь, что вам нужно создать купоны в нескольких местах и обновить способ их создания: просто работаете со своими классами Service и Request, и все готово!

 

Автор: François Louchart
Перевод: Demiurge Ash