Skip to main content

Wat zijn facades?

Facades bieden een “statische” interface naar klassen die beschikbaar zijn in de servicecontainer van je applicatie. Laravel wordt geleverd met veel facades die toegang geven tot vrijwel alle functionaliteit. Laravel-facades werken als “statische proxy’s” naar de onderliggende klassen in de servicecontainer en bieden een beknopte, expressieve syntaxis, terwijl ze beter testbaar en flexibeler blijven dan traditionele statische methoden. Alle Laravel-facades zijn gedefinieerd in de namespace Illuminate\Support\Facades.
Het is geen probleem als je het mechanisme achter facades nog niet volledig begrijpt. Leer eerst hoe je ze gebruikt en ga verder met het leren van Laravel.

Hoe facades werken

In een Laravel-applicatie is een facade een klasse die toegang biedt tot een object uit de container. Dit mechanisme wordt gerealiseerd door de Facade-klasse. Alle facades van Laravel, en ook je eigen facades, extenden de basisklasse Illuminate\Support\Facades\Facade. De Facade-basisklasse gebruikt de magic method __callStatic() om aanroepen op de facade te delegeren naar het object dat uit de container is geresolved.
Bovenaan het bestand importeren we de Cache-facade. Deze facade proxyt de toegang tot de implementatie van de Illuminate\Contracts\Cache\Factory-interface. Alle aanroepen via de facade worden doorgegeven aan de onderliggende instantie van de cacheservice van Laravel. Als je naar de klasse Illuminate\Support\Facades\Cache kijkt, zie je dat er geen statische methode get bestaat.
De Cache-facade extendt de basisklasse Facade en definieert de methode getFacadeAccessor(). Deze methode geeft de naam van de servicecontainerbinding terug. Wanneer een gebruiker een statische methode op de Cache-facade aanroept, resolvet Laravel de cache-binding uit de servicecontainer en voert het de gevraagde methode (in dit geval get) op dat object uit.

Wanneer wel en niet facades gebruiken

Voordelen van facades

Facades hebben veel voordelen. Ze bieden een beknopte, gemakkelijk te onthouden syntaxis waarmee je de functionaliteit van Laravel kunt gebruiken zonder lange klassennamen te hoeven onthouden die je handmatig moet injecteren en configureren. Bovendien zijn ze door hun unieke gebruik van de dynamische methoden van PHP eenvoudig te testen.

Pas op voor scope creep

Het grootste gevaar bij het gebruik van facades is “scope creep” van je klassen. Omdat facades makkelijk te gebruiken zijn en geen injectie vereisen, is het verleidelijk om je klassen te laten groeien en steeds meer facades te gebruiken. Bij dependency injection geeft een grote constructor je visuele feedback. Let bij het gebruik van facades dus op de omvang van je klassen en houd hun verantwoordelijkheden beperkt.
Als je het gevoel hebt dat een klasse te groot wordt, overweeg dan om die op te splitsen in meerdere kleinere klassen.

Facades vs. dependency injection

Een van de belangrijkste voordelen van dependency injection is dat je de implementatie van een geïnjecteerde klasse kunt vervangen. Dat is handig bij het testen: je kunt een mock of stub injecteren en asserteren dat verschillende methoden op de stub zijn aangeroepen. Echt statische klassemethoden kun je normaal gesproken niet mocken of stubben, maar omdat facades dynamische methoden gebruiken om methodeaanroepen te proxyen naar objecten die uit de servicecontainer zijn geresolved, kun je facades net zo testen als een geïnjecteerde klasse-instantie.
Voor deze route kun je de volgende test schrijven om te verifiëren dat Cache::get met de verwachte argumenten is aangeroepen.

Facades vs. helperfuncties

Naast facades biedt Laravel “helper”-functies waarmee je veelvoorkomende taken kunt uitvoeren, zoals views genereren, events afvuren, jobs dispatchen en HTTP-responses versturen. Veel helperfuncties bieden dezelfde functionaliteit als hun bijbehorende facade.
Er is geen praktisch verschil tussen facades en helperfuncties. Ook wanneer je helperfuncties gebruikt, kun je ze op dezelfde manier testen als de bijbehorende facade.

Real-time facades

Met real-time facades kun je elke klasse in je applicatie als facade behandelen. Om het gebruik uit te leggen, kijken we eerst naar code zonder real-time facades. Stel bijvoorbeeld dat het Podcast-model een publish-methode heeft. Om de podcast te publiceren, moet echter een Publisher-instantie worden geïnjecteerd.
Met real-time facades hoef je de Publisher-instantie niet meer expliciet door te geven, terwijl je dezelfde testbaarheid behoudt. Om een real-time facade te genereren, zet je de prefix Facades voor de namespace van de klasse die je importeert.
Wanneer een real-time facade wordt gebruikt, wordt de publisher-implementatie uit de servicecontainer geresolved op basis van het gedeelte van de interface- of klassennaam dat na de Facades-prefix komt.
Real-time facades zijn handig wanneer je het mocken in tests eenvoudig wilt houden en tegelijkertijd niet langer als argument wilt hoeven doorgeven.

Facades testen

Om facades te testen gebruik je de shouldReceive-methode. Deze geeft een Mockery-mockinstantie terug. Omdat facades feitelijk door de servicecontainer worden geresolved en beheerd, zijn ze veel gemakkelijker te testen dan gewone statische klassen.
Veelgebruikte mockmethoden:

Overzicht van de belangrijkste facades

Een overzicht van veelgebruikte facades, hun onderliggende klassen en de bindingnamen in de servicecontainer.

Volgende stappen

Contracts

Leer het concept van Contracts, de tegenhanger van facades, en wanneer je welke gebruikt.
Laatst gewijzigd op 6 september 2026