The concept of facades is not exactly the same in general programming and Laravel. Something that took me a while to understand. A facade is a facade, right? Wrong. Although, to me, they do seem kind of similar.
Facades in general programming
In general programming, the term "facade" is a design pattern where a simplified interface is provided for a more complex code, making it easier to use and understand. Facades are abstractions that allow you to interact with the system without needing to understand its inner workings. I don't care how the TV remote works under the hood and how it controls the TV; I just want to click a button to switch the TV on. The remote is a facade.
Facades in Laravel
In Laravel, a facade also provides a simplified interface. This is done by providing a static interface for classes available in the service container and allowing you to use static methods to call non-static resources. This means I can use the ::
syntax without newing the class first and without the class having to have static methods.
One example of a facade is the Route
facade.
Route::get('/', fn() {...});
I'm calling the get()
function using the scope resolution operator (::). But the get()
function is not static, it's public. Have a look yourself here Illuminate\Routing\Router
. I shouldn't be able to call a nonstatic function using ::
. But thanks to the Route facade, I can.
Real-time facades in Laravel
You can add the word Facades
to the beginning of your namespace, and it will turn that class into a Facade. That doesn't mean I need to move the class into the Facades
directory or do anything else with it. No, it can stay where it is, I just need to prefix the use statement when I import the namespace into a class.
<?php
use App\Services\PodcastNotification as Notification;
class Podcast {
public function publish(): void
{
// (...)
(new Notification)->notify();
}
}
App\Services\PodcastNotification
is not a facade, so the methods in this class must be called by new-ing up the class first. But if I prefix it with the word Facade, Facades\App\Services\UpgradeNotification
, it becomes a real-time facade, and its methods can be called using the ::
syntax.
<?php
use Facade\App\Services\PodcastNotification as Notification;
class Podcast {
public function publish(): void
{
// (...)
Notification::notify();
}
}
The downsides
However, it's also important to know that there are many developers who do not like to use facades in Laravel; they actively avoid them. There are a few reasons for that. One of them is that using facades introduces a hidden dependency. Considering the Route
facade again, it actually resolves to Illuminate\Routing\Router
. But since I am using a facade, not a dependency injection, I wouldn't know this is the underlying class unless I dig into the code. The Route
facade is just a middleman to make the static-like syntax work, but it hides the actual implementation, which some developers do not like.
So, are facades in Laravel and in general programming totally different concepts? At a top level, I don't think so. Laravel's facades do simplify access to the underlying class, which is what facades as a design pattern are supposed to do 🤷♀️. But the implementation is very different.
Either way, now you know, so go forth and prosper. 🚀