• Час читання ~6 хв
  • 27.03.2023

Ви коли-небудь використовували Auth::user() в Laravel? Так що так, це Auth фасад. Питання: чи потрібно вам насправді знати, як вони працюють, і чи потрібно вам створювати власні фасади?

Відмова від відповідальності: ця стаття написана Модестасом, більше схожа на думку. Фасади - одна з тих тем, які мають різні думки навколо себе, тому я відкритий до дискусій тут або в Twitter.


Що таке фасади?

По-перше, визначення.

Читаючи документацію Laravel про фасади, ви можете трохи заплутатися в тому, що це таке. У документації сказано:

Фасади забезпечують «статичний» інтерфейс класів, які доступні в сервісному контейнері програми.

Поряд з цим, вони також кажуть

: Laravel Facades служать «статичними проксі» для базових класів у сервісному контейнері, забезпечуючи переваги терсе, експресивного синтаксису, зберігаючи при цьому більшу тестовість і гнучкість, ніж традиційні статичні методи.

Зачекайте, що це насправді означає?

Ну, вам не доведеться знати, який клас знаходиться під фасадом. Можна просто викликати Auth фасад і способи доступу з базового класу.

Фасади в дії

У Ларавелі ми можемо зателефонуватиAuth::user(), щоб отримати користувача з сеансу.

Те, чого ми не бачимо під капотом, це статичний проксі для Illuminate\Auth\AuthManager класу. Клас AuthManager має метод, який називаєтьсяuser(), який повертає користувача з сеансу.

Фасад полегшує наш досвід як розробників, оскільки ми повинні пам'ятати Auth лише фасад, і ми отримуємо миттєвий статичний доступ до user() методу.

Давайте швидко порівняємо використання фасаду з використанням самого класу, щоб проілюструвати різницю.

Як би це виглядало без фасадів?

Створення нового екземпляра

use Illuminate\Auth\AuthManager;

public function index()
{
    $auth = new AuthManager();
    $user = $auth->user();
}

класу Або, трохи коротше, з ін'єкцією залежності.

Використання ін'єкції

use Illuminate\Auth\AuthManager;

public function index(AuthManager $auth)
{
    $user = $auth->user();
}

залежності З Фасадом під капотом це всього лише одна лінія.

Використання фасаду

public function index()
{
    $user = Auth::user();
}

Отже, коротше кажучи, Фасади - це просто ярлик до певного класу.

Тепер, коли ми знаємо, що вони собою являють, давайте подумаємо, чи потрібно нам їх використовувати, і як.


ВИКОРИСТАННЯ фасадів - це чудово

Давайте почнемо з того, що я вважаю хорошим у використанні фасадів.

Використовуйте фасади від Framework Core

Зручно використовувати фасади з ядра Laravel. Це просто працює, і вам не потрібно запам'ятовувати жодне з довгих назв класів.

Чудово підходить для тих, хто вчиться запускати речі. Дуже добре підходить для тих, хто швидко розробляє системи.

Уявіть, якби вам довелося запам'ятати все це:Набагато краще швидко запам'ятати їх фасади та використовувати їх:


Використовуйте фасади від Packages

Package Творці також можуть отримати користь від фасадів з тієї ж причини, що і ми маємо в самому фреймворку - легше запам'ятати назву Фасаду, ніж назву класу. Давайте розглянемо кілька прикладів пакетів:

Журнали

активності Spatie https://spatie.be/docs/laravel-activitylog/v4/advanced-usage/batch-logs

У цьому пакеті ми можемо знайти фасад, який називається LogBatch ярликом для Spatie\Activitylog\LogBatch класу.

Laravel Debugbar

https://github.com/barryvdh/laravel-debugbar Цей пакет також містить фасад, який називаєтьсяDebugbar, що є ярликом для Barryvdh\Debugbar\LaravelDebugbar класу.

Це просто дає кінцевому користувачеві кращу взаємодію для статичного використання певної функціональності в будь-який момент.


СТВОРЕННЯ власних фасадів: Не так чудово

, о круто, так що ви думаєте, що можете створити власні «ярлики» фасадів і використовувати їх в будь-якому місці у вашому додатку Laravel?

І ось та частина, де, на мою думку, фасади не такі хороші. Використані неправильним чином, вони можуть викликати проблеми з оснащенням або загальним досвідом.

Проблеми з автозаповненням

Коли ви використовуєте фасади, ви не маєте доступу до методів, доступних у класі. Це може спричинити деякі проблеми з автозаповненням у вашій IDE.

Наприклад, уявіть, що у вас є клас обслуговування під назвою метод :

get()app/Services/SearchService.php Щоб створити до нього "ярлик", ви створюєте фасад під назвою SearchService Search:

namespace App\Services\SearchService;

class SearchService
{
    public function get(string $query): array
    {
        // ...
    }
}

namespace App\Services\Facades;

use Illuminate\Support\Facades\Facade;

class Search extends Facade
{
    protected static function getFacadeAccessor()
    {
        return \App\Services\SearchService::class;
    }
}

Тож тепер ви можете використовувати Search::get(), чи не так?

Круто, але ваша IDE може не показати, що клас існує або що в ньому немає методів!

І це правда, тому що ваш клас Facade не має get() методу в ньому.

Ви можете змусити автозаповнення IDE працювати, додавши блоки документів до класу

namespace App\Services\Facades;

/**
 * @method static get(string $query)
 */
class Search extends Facade {
    // ...
}

що всі методи додані до фасаду. Здається складним.


Фасади можуть перевизначати назви класів

Коли ви створюєте фасад, вам не потрібно слідувати тій самій назві класу, яку ви маєте намір назвати. Це означає, що я можу використовувати будь-яке ім'я, яке захочу для Фасаду, і воно все одно буде працювати. Давайте розглянемо приклад:

Створення конфігурації/додатка фасаду.php

class MyRandomClassName extends Facade
{
    protected static function getFacadeAccessor()
    {
        return \App\Services\SearchService::class;
    }
}

Використання

// ...
'aliases' => Facade::defaultAliases()->merge([
    // ...
    'MyRandomClassName' => \App\Services\Facades\MyRandomClassName::class,
])->toArray(),

фасаду

\MyRandomClassName::get('query');

І тепер я можу використовувати MyRandomClassName фасад для виклику Search класу. Імпорт не потрібен, оскільки ви можете отримати доступ до нього в усьому світі.

Ще гіршим є той факт, що цього класу може навіть не бути! Як? Що ж, ми створюємо псевдонім. Давайте трохи змінимо config a:

Використання

// ...
'aliases' => Facade::defaultAliases()->merge([
    // ...
    'MadeUpAlias' => \App\Services\Facades\MyRandomClassName::class,
])->toArray(),

фасаду

\MadeUpAlias::get('query');

фасадуІ це все одно спрацює! Але якщо ви спробуєте шукати глобально , MadeUpAliasрезультатів не буде. Це тому, що це не справжній клас. Це просто псевдонім для класу, який існує.

Зверніть увагу: Я знаю, що цей приклад перебільшений. Але це дає вам чудовий приклад того, як ви можете використовувати фасади неправильним способом, щоб додати більше плутанини до вашої кодової бази.


Фасади можна використовувати де завгодно Одна річ, яку мають для них фасади, - це можливість використовувати їх де

завгодно. Чудова річ, правда?

Вам це потрібно в поданні, контролері, службі чи де-небудь ще? Немає проблем - він є.

Але це швидкий спосіб зламати шаблон MVC і запустити складну логіку там, де ви не повинні.

Уявіть, що ви створили фасад для сервісу, який генерує велику таблицю звітів. Використовуйте його в контролері, і це буде добре. Але використовуйте його в View, і у нас є проблема.


Підручники з фасадів не показують реального використання

Коли ви дивитеся на навчальні посібники про те, як створити фасади, вони, як правило, дуже прості. Вони є лише ярликом до класу, який повертає щось просте.

Але в реальних сценаріях фасади призначені для використання як проксі-класу, щоб отримати статичний доступ до методів, які не є статичними, як у Auth Facade.

Коли він перестає бути крутим, ви можете швидко вийти з-під контролю і перемістити все на фасади, що швидко призведе вас до повзучості масштабу, і один клас може почати виконувати роботу 10 інших.


Висновок

Я б сказав, що фасади зручні і прості у використанні, починаючи від рамок і пакетів. Але якщо ми спробуємо створити ваші фасади - ця історія зміниться. Тоді ви повинні дійсно знати, що ви робите.

Було б краще подумати про те, як ви можете структурувати проект з різними шаблонами дизайну, щоб уникнути глобального класу (фасаду), який можна назвати де завгодно.

Як ти гадаєш? Давайте обговоримо в коментарях!

Comments

No comments yet
Yurij Finiv

Yurij Finiv

Full stack

Про мене

Professional Fullstack Developer with extensive experience in website and desktop application development. Proficient in a wide range of tools and technologies, including Bootstrap, Tailwind, HTML5, CSS3, PUG, JavaScript, Alpine.js, jQuery, PHP, MODX, and Node.js. Skilled in website development using Symfony, MODX, and Laravel. Experience: Contributed to the development and translation of MODX3 i...

Про автора CrazyBoy49z
WORK EXPERIENCE
Контакти
Ukraine, Lutsk
+380979856297