• Czas czytania ~5 min
  • 27.03.2023

Czy kiedykolwiek używałeś Auth::user() w Laravel? Więc tak, to Auth jest fasada. Pytanie: czy naprawdę musisz wiedzieć, jak działają i czy musiałbyś stworzyć własne fasady?

Zastrzeżenie: ten artykuł został napisany przez Modestas, bardziej jak opinia. Fasady to jeden z tych tematów, które mają różne opinie na ich temat, więc jestem otwarty na dyskusje tutaj lub na Twitterze.


Czym są fasady?

Po pierwsze, definicja.

Czytając dokumentację Laravel na temat fasad, możesz być trochę zdezorientowany co do tego, czym one są. Dokumentacja mówi:

Fasady zapewniają "statyczny" interfejs do klas, które są dostępne w kontenerze usług aplikacji.

Oprócz tego mówią również:

Fasady Laravel służą jako "statyczne proxy" dla podstawowych klas w kontenerze usług, zapewniając korzyści z lakonicznej, ekspresyjnej składni przy zachowaniu większej testowalności i elastyczności niż tradycyjne metody statyczne.

Zaraz, co to właściwie znaczy?

Cóż, nie musisz wiedzieć, jaka klasa znajduje się pod fasadą. Możesz po prostu wywołać metody fasady Auth i dostępu z klasy bazowej.

Fasady w akcji

W Laravel możemy zadzwonićAuth::user(), aby pobrać użytkownika z sesji.

To, czego nie widzimy pod maską, to statyczny serwer proxy dla Illuminate\Auth\AuthManager klasy. Klasa AuthManager ma metodęuser(), która zwraca użytkownika z sesji.

Fasada ułatwia nam doświadczenie jako programistów, ponieważ musimy pamiętać tylko fasadę Auth i uzyskujemy natychmiastowy statyczny user() dostęp do metody.

Szybko porównajmy wykorzystanie elewacji z wykorzystaniem samej klasy, aby zilustrować różnicę.

Jak wyglądałby bez fasad?

Tworzenie nowej instancji

use Illuminate\Auth\AuthManager;

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

klasy Lub, nieco krócej, z Dependency Injection.

Korzystanie z wstrzykiwania

use Illuminate\Auth\AuthManager;

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

zależności Z fasadą pod maską to tylko jedna linia.

Korzystanie z funkcji Fasada

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

Krótko mówiąc, fasady są jak skrót do konkretnej klasy.

Teraz, kiedy wiemy, czym one są, zastanówmy się, czy musimy ich używać i jak.


UŻYWANIE fasad jest świetne

Zacznijmy od tego, co uważam za dobre w używaniu fasad.

Użyj fasad z Framework Core

Wygodnie jest używać fasad z rdzenia Laravel. To po prostu działa i nie musisz pamiętać żadnej z długich nazw klas.

Idealne dla tych, którzy uczą się działać. Idealne dla tych, którzy szybko rozwijają systemy.

Wyobraź sobie, że musisz zapamiętać wszystkie z nich:O wiele lepiej jest szybko zapamiętać ich fasady i używać ich:

Użyj fasad z pakietów Twórcy pakietów


mogą również korzystać z fasad z tego samego powodu,

co mamy w samym frameworku - łatwiej jest zapamiętać nazwę fasady niż nazwę klasy. Spójrzmy na kilka przykładów pakietów:

Spatie Activity Logs

https://spatie.be/docs/laravel-activitylog/v4/advanced-usage/batch-logs

W tym pakiecie możemy znaleźć Facade o nazwieLogBatch, która jest skrótem do Spatie\Activitylog\LogBatch klasy.

Laravel Debugbar

https://github.com/barryvdh/laravel-debugbar Ten pakiet zawiera również Facade o nazwie Debugbar Skrót do Barryvdh\Debugbar\LaravelDebugbar klasy.

Daje to po prostu użytkownikowi końcowemu lepszą interakcję, aby korzystać z niektórych funkcji w dowolnym momencie statycznie.


TWORZENIE własnych fasad: Nie tak wspaniałe

Och, fajnie, więc możesz stworzyć własne "skrótowe" fasady i używać ich w dowolnym miejscu w aplikacji Laravel?

A oto część, w której uważam, że fasady nie są tak dobre. Użyte w niewłaściwy sposób mogą powodować problemy z narzędziami lub ogólnym doświadczeniem.

Problemy z automatycznym uzupełnianiem

Gdy używasz fasad, nie masz dostępu do metod dostępnych w klasie. Może to powodować pewne problemy z automatycznym uzupełnianiem w IDE.

Załóżmy na przykład, że masz klasę Service o nazwie, która ma metodę o nazwie :app/Services/SearchService.php Aby utworzyć do niego "skrót", należy utworzyć fasadę o SearchService nazwie get()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;
    }
}

Więc teraz możesz użyć Search::get(), prawda?

Fajnie, ale twoje IDE może nie pokazać, że klasa istnieje lub że nie ma żadnych metod!

I to prawda, ponieważ twoja klasa fasady nie ma w sobie metodyget().

Możesz sprawić, że autouzupełnianie IDE będzie działać, dodając bloki dokumentów do klasy

namespace App\Services\Facades;

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

Ale będziesz także musiał zarządzać innym plikiem, aby upewnić się, że wszystkie metody są dodawane do fasady. Wydaje się skomplikowane.


Fasady mogą przesłaniać nazwy klas

Podczas tworzenia fasady nie trzeba podążać za tą samą nazwą klasy, którą ma zostać wywołana. Oznacza to, że mogę użyć dowolnej nazwy dla fasady i nadal będzie działać. Spójrzmy na przykład:

Tworzeniekonfiguracji/aplikacjifasady.php

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

Użycie

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

fasady A teraz mogę użyć fasady

\MyRandomClassName::get('query');

MyRandomClassName, aby wywołać klasę.Search Import nie jest potrzebny, ponieważ można uzyskać do niego dostęp na całym świecie.

Jeszcze gorszy jest fakt, że ta klasa może nawet nie istnieć! Jak? Cóż, tworzymy alias. Zmieńmy trochęconfig:

Użycie

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

fasady A teraz mogę użyć fasady

\MadeUpAlias::get('query');

fasadyI to nadal będzie działać! Ale jeśli spróbujesz wyszukać globalnie , MadeUpAliasnie będzie żadnych wyników. To dlatego, że nie jest to prawdziwa klasa. To tylko alias klasy, która istnieje.

Uwaga: Wiem, że ten przykład jest przesadzony. Ale daje świetny przykład tego, jak możesz używać fasad w niewłaściwy sposób, aby dodać więcej zamieszania do swojej bazy kodu.


Fasady mogą być używane w dowolnym miejscu Jedną z rzeczy, które mają dla nich fasady, jest możliwość korzystania z nich w dowolnym miejscu

. Świetna sprawa, prawda?

Czy potrzebujesz go w widoku, kontrolerze, usłudze lub gdziekolwiek indziej? Nie ma problemu - jest.

Ale jest to szybki sposób na przełamanie wzorca MVC i uruchomienie złożonej logiki tam, gdzie nie powinieneś.

Wyobraź sobie, że utworzyłeś fasadę dla usługi, która generuje dużą tabelę raportów. Użyj go w kontrolerze, a będzie dobrze. Ale użyj go w widoku, a mamy problem.


Samouczki dotyczące fasad nie pokazują rzeczywistego użycia

Kiedy patrzysz na samouczki dotyczące tworzenia fasad, są one zwykle bardzo proste. Są tylko skrótem do klasy, która zwraca coś prostego.

Jednak w rzeczywistych scenariuszach fasady mają być używane jako klasa proxy, aby uzyskać statyczny dostęp do metod, które nie są statyczne, jak w fasadzieAuth.

Kiedy przestaje być fajnie, możesz szybko wymknąć się spod kontroli i przenieść wszystko na fasady, co szybko doprowadziłoby cię do pełzania zakresu, a jedna klasa może zacząć wykonywać pracę 10 innych.


Wniosek

Powiedziałbym, że fasady są wygodne i łatwe w użyciu, od ram i pakietów. Ale jeśli spróbujemy stworzyć twoje fasady - ta historia się zmieni. Musisz więc naprawdę wiedzieć, co robisz.

Lepiej byłoby pomyśleć o tym, jak można zorganizować projekt za pomocą różnych wzorców projektowych, aby uniknąć globalnej klasy (fasady), którą można wywołać w dowolnym miejscu.

Co myślisz? Porozmawiajmy w komentarzach!

Comments

No comments yet
Yurij Finiv

Yurij Finiv

Full stack

O

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...

O autorze CrazyBoy49z
WORK EXPERIENCE
Kontakt
Ukraine, Lutsk
+380979856297