Facades in Laravel

Published on March 25th, 2024

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

← Go back