Qu’est-ce qu’une façade
Une façade fournit une interface « statique » aux classes disponibles dans le conteneur de services de l’application. Laravel inclut de nombreuses façades qui donnent accès à presque toutes ses fonctionnalités. Les façades agissent comme des « proxys statiques » vers des classes concrètes du conteneur de services, offrant une syntaxe concise et expressive tout en étant plus testables et plus flexibles que les méthodes statiques classiques. Toutes les façades Laravel sont définies dans le namespaceIlluminate\Support\Facades.
Il n’est pas nécessaire de comprendre totalement leur fonctionnement pour les utiliser. Commencez par les utiliser et poursuivez votre apprentissage de Laravel.
Fonctionnement des façades
Dans une application Laravel, une façade est une classe qui fournit un accès à un objet du conteneur. Ce mécanisme est assuré par la classeFacade. Toutes les façades de Laravel (et vos façades personnalisées) héritent de la classe de base Illuminate\Support\Facades\Facade.
La classe Facade de base utilise la méthode magique __callStatic() pour déléguer les appels sur la façade à l’objet résolu par le conteneur.
Cache. Elle fait office de proxy vers l’implémentation de l’interface Illuminate\Contracts\Cache\Factory. Tous les appels via cette façade sont transmis à l’instance interne du service de cache.
Regardons la classe Illuminate\Support\Facades\Cache : la méthode statique get n’y existe pas.
Cache étend Facade et définit getFacadeAccessor(). Cette méthode retourne le nom du binding dans le conteneur. Quand on appelle une méthode statique sur Cache, Laravel résout le binding cache depuis le conteneur puis exécute la méthode demandée (ici get) sur l’objet obtenu.
Quand utiliser (ou éviter) les façades
Avantages des façades
Les façades offrent une syntaxe concise et mémorisable pour utiliser Laravel sans avoir à retenir des noms de classes longs à injecter et configurer. Grâce à l’utilisation particulière des méthodes dynamiques PHP, elles sont aussi faciles à tester.Attention au scope creep
Le principal risque est le « gonflement » de vos classes. Les façades étant simples à utiliser et sans injection, on est tenté d’en ajouter de plus en plus. Avec l’injection de dépendances, un constructeur volumineux vous alerte visuellement. Restez donc attentif à la taille de vos classes et gardez leurs responsabilités restreintes.Façades vs. injection de dépendances
L’un des grands atouts de l’injection est la possibilité de substituer l’implémentation d’une classe injectée. Utile pour les tests : on injecte un mock/stub et on vérifie les appels de méthodes. Les méthodes statiques réelles ne peuvent pas être mockées en général, mais les façades s’appuient sur des méthodes dynamiques qui délèguent au conteneur. On peut donc les tester comme une instance injectée.Cache::get a été appelée avec les bons arguments.
Façades vs. helpers
Outre les façades, Laravel propose des fonctions « helper » pour les tâches courantes : créer une vue, déclencher un événement, dispatcher un job, envoyer une réponse HTTP, etc. Beaucoup de helpers font la même chose que la façade correspondante.Façades en temps réel
Les façades en temps réel permettent de traiter n’importe quelle classe de l’application comme une façade. Voyons d’abord un code sans façade en temps réel. Supposons que le modèlePodcast ait une méthode publish. Publier un podcast nécessite d’injecter une instance Publisher.
Publisher tout en gardant la testabilité. On préfixe le namespace de la classe importée par Facades.
Facades est résolue par le conteneur pour obtenir l’implémentation du publisher.
Tests des façades
Pour tester une façade, utilisezshouldReceive qui retourne une instance mock Mockery. Comme la façade est résolue via le conteneur, elle est bien plus testable qu’une classe statique classique.
| Méthode | Description |
|---|---|
shouldReceive('method') | S’attend à ce que la méthode soit appelée |
once() | Une seule fois |
times(n) | n fois |
with(args) | Avec des arguments donnés |
andReturn(value) | Retourne la valeur spécifiée |
andReturnNull() | Retourne null |
Principales façades
Correspondance entre façades courantes, leur classe concrète et le nom du binding du conteneur.| Façade | Classe | Binding |
|---|---|---|
App | Illuminate\Foundation\Application | app |
Auth | Illuminate\Auth\AuthManager | auth |
Cache | Illuminate\Cache\CacheManager | cache |
Config | Illuminate\Config\Repository | config |
Cookie | Illuminate\Cookie\CookieJar | cookie |
Crypt | Illuminate\Encryption\Encrypter | encrypter |
DB | Illuminate\Database\DatabaseManager | db |
Event | Illuminate\Events\Dispatcher | events |
File | Illuminate\Filesystem\Filesystem | files |
Gate | Illuminate\Contracts\Auth\Access\Gate | — |
Hash | Illuminate\Contracts\Hashing\Hasher | hash |
Http | Illuminate\Http\Client\Factory | — |
Log | Illuminate\Log\LogManager | log |
Mail | Illuminate\Mail\Mailer | mailer |
Notification | Illuminate\Notifications\ChannelManager | — |
Queue | Illuminate\Queue\QueueManager | queue |
RateLimiter | Illuminate\Cache\RateLimiter | — |
Redirect | Illuminate\Routing\Redirector | redirect |
Request | Illuminate\Http\Request | request |
Route | Illuminate\Routing\Router | router |
Schema | Illuminate\Database\Schema\Builder | — |
Session | Illuminate\Session\SessionManager | session |
Storage | Illuminate\Filesystem\FilesystemManager | filesystem |
URL | Illuminate\Routing\UrlGenerator | url |
Validator | Illuminate\Validation\Factory | validator |
View | Illuminate\View\Factory | view |
Prochaines étapes
Contrats
Découvrez le concept de contrats, complément des façades, et quand les utiliser.