Automated bad practice

Reading Time: 3 minutes
When did Cache::get(); become hotter than $this->cache->get();

One new feature of Laravel 5.4 are so-called “Automatic Facades”. My colleague was expecting my reaction when he sends me the link to the blog entry announcing this feature (I’m not linking it intentionally) with a thievish smile.

As Laravel’s documentation puts it, “Facades provide a static interface to classes that are available in the application’s service container”. In other words, you can access any class almost everywhere without hassling about nasty things like dependency injection. Hm? Do I hear Singleton somewhere?

So far it was required to add Facade classes in order to make this work. It seems even this little barrier has fallen now.

Laravel’s Facade, in my opinion, is one of the worst features a PHP framework offers nowadays. After times of Zend Framework 1 and the infamous Registry (I abused it too), when IoC finally arrived in the PHP world, it somehow seemed to me as quite a setback when Laravel became more and more popular with its Facade feature (it’s not even the Facade design pattern anyway).

Here’s why.

1. It’s tempting

Making classes available in the code everywhere is tempting inexperienced (and experienced) developers to use the facade everywhere, without thinking if this might be a good idea or not. I’ve seen things! I even found Facade in configuration files. IN CONFIG FILES WTF!!1

If you don’t pay close attention, your classes soon will violate the single responsibility principle, simply because you don’t really notice how many dependencies you suddenly use.

2. It binds your code

In my opinion, code should be bound as less to the underlying framework as possible. I totally get the advantages of ORMs and such, I’m not opting against packages etc., but binding your code too close to a framework can cause problems if you want to use your business logic over longer terms.

But well, I guess if you are willing to use non-namespaced helper functions everywhere in your code (another Laravel feature I “deeply adore”), you don’t really care about this either.

3. It requires more overhead to test

“But Facades are more testable than traditional static methods!” I hear the Artisans yell. Yeah, sure, that is true.

What a benefit!

It just requires bootstrapping of Laravel for every test, making unit tests significantly slower. Your tests will become more complex and thus require more maintenance, as you will need to mock more dependencies which are all required to make one test work.

4. It’s actually not that convenient

Any modern IDE provides Code completion, so I can see in a second which methods a class offers. With Facade, I need an additional package that parses the Facades and generates documentation files that the IDE can parse for the Code completion.

How convenient!

When stepping through the code during debugging it annoys me pretty much to go through the facade over and over again. It’s just so unnecessary…

Probably both IDE and Debuggers are not so commonly used amongst Artisans?

5. It’s not more expressive

I really don’t get why

Cache::get('key')

is more “expressive” than

$this->cache->get('key')

Somebody needs to explain!

Fair enough

To be fair, even the official Laravel documentation states that Facade should not be used when building a third-party package, and that it bears some of the above mentioned risks. So Taylor is aware of it. But then why is this feature enforced in the first place anyway? I think it’s because Laravel claims to be so “expressive” and “beautiful” in it’s syntax that everybody accepts the downsides.

Decide for yourself if it is worth it.

Probably I’m just missing the point here? Why do you think Laravel’s Facade should be used rather than Dependency Injection?

5 thoughts on “Automated bad practice”

  1. I absolutely agree with you. Laravel’s Facades are evil. After CodeIgniter project was depreceated I found Laravel because It was very easy to use thanks to Facades. Although I could do everything with Laravel, I didn’t learn SOLID principles and design patterns for a long time. Today lots of spaghetti project was developing thanks to Laravel. Laravel is a good project but developers use it conscious.

    1. Right, that’s exactly what I meant.

      Of course projects can be done proper with Laravel, but it’s tempting to do it quick. That is cool for prototypes, but if you plan to maintain a project over a longer time, better invest a bit more effort and don’t use facades.

  2. One of the “features” that someone one might go “That’s neat”, is that the Request class object also includes validation methods. Definitely breaks the first rule of fight club, er SOLID.

  3. What about Laravel helpers? I found them quite useful. And if you decide to move to another framework in worst case scenario you can copy implementation:-)

    1. I agree they are helpful. However they kind of “pollute” the global namespace, and if you look at the helpers more in detail, you’ll find they often just wrap calls to classes like Str or Arr (which e.g. again uses Collection – I stopped digging deeper at that point) or instantiate objects like Optional.

      So be aware that you might need to copy quite some logic in the worst case 😉

Leave a Reply

Your email address will not be published. Required fields are marked *

I accept the Privacy Policy

This site uses Akismet to reduce spam. Learn how your comment data is processed.