Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel 4: Facade vs DI (when to use)

My understanding is that a facade is used as an alternative to dependency injection. Please correct if I'm mistaken. What is not clear is when one should use one or the other.

What are the advantages/disadvantages of each approach? How should I determine when to use one or the other?

Lastly, why not use both? I can create a facade that references an interface. It seems Sentry 2 is written this way. Is there a best practice?

like image 691
kablamus Avatar asked Oct 05 '13 03:10

kablamus


People also ask

Why facade is important in Laravel?

Laravel ships with many facades which provide access to almost all of Laravel's features. Laravel facades serve as "static proxies" to underlying classes in the service container, providing the benefit of a terse, expressive syntax while maintaining more testability and flexibility than traditional static methods.

Why DI is needed?

Why do I need a DI Box? A DI box is primarily used to allow you to run a long cable from an instrument such as an electric guitar or bass guitar without adding noise or losing signal quality. High impedance signals tend to be much more prone to noise and keeping cable lengths under 8 meters (25 ft) is recommended.

What is the facade pattern used for Laravel?

A facade in Laravel is a wrapper around a non-static function that turns it into a static function. The word "wrapper" can also be used when describing design patterns. Wrapping an object to provide a simplified interface to it is often described as the "facade" pattern. So in short, the wrapper is the facade.

Where will you define Laravel's facades?

Laravel facades serve as static proxies to underlying classes in the service container, providing the benefit of a terse, expressive syntax while maintaining more testability and flexibility than traditional static methods.


2 Answers

FACADES

Facades are not an alternative to dependency injection.

Laravel Facade is an implementation of the Service Locator Pattern, creating a clean and beautiful way of accessing objects:

MyClass::doSomething();

This is the PHP syntax for a static methods, but Laravel changes the game and make them non-static behind the scenes, giving you a beautiful, enjoyable and testable way of writing your applications.

DEPENDENCY INJECTION

Dependency Injection is, basically, a way of passing parameters to your constructors and methods while automatically instatiating them.

class MyClass {

    private $property;

    public function __construct(MyOtherClass $property)
    {
        /// Here you can use the magic of Dependency Injection

        $this->property = $property

        /// $property already is an object of MyOtherClass
    }

}

A better construction of it would be using Interfaces on your Dependency Injected constructors:

class MyClass {

    private $property;

    public function __construct(MyInterface $property)
    {
        /// Here you can use the magic of Dependency Injection

        $this->property = $property

        /// $property will receive an object of a concrete class that implements MyInterface
        /// This class should be defined in Laravel elsewhere, but this is a way of also make 
        /// your application easy to maintain, because you can swap implementations of your interfaces
        /// easily
    }

}

But note that in Laravel you can inject classes and interfaces the same way. To inject interfaces you just have to tell it wich one will be this way:

App::bind('MyInterface', 'MyOtherClass');

This will tell Laravel that every time one of your methods needs an instance of MyInterface it should give it one of MyOtherClass.

What happens here is that this constuctor has a "dependency": MyOtherClass, which will be automatically injected by Laravel using the IoC container. So, when you create an instance of MyClass, Laravel automatically will create an instance of MyOtherClass and put it in the variable $class.

Dependency Injection is just an odd jargon developers created to do something as simple as "automatic generation of parameters".

WHEN TO USE ONE OR THE OTHER?

As you can see, they are completely different things, so you won't ever need to decide between them, but you will have to decide where go to with one or the other in different parts of your application.

Use Facades to ease the way you write your code. For example: it's a good practice to create packages for your application modules, so, to create Facades for those packages is also a way to make them seem like a Laravel public class and accessing them using the static syntax.

Use Dependency Injection every time your class needs to use data or processing from another class. It will make your code testable, because you will be able to "inject" a mock of those dependencies into your class and you will be also exercising the single responsibility principle (take a look at the SOLID principles).

like image 115
Antonio Carlos Ribeiro Avatar answered Sep 18 '22 20:09

Antonio Carlos Ribeiro


Facades, as noted, are intended to simplify a potentially complicated interface.

Facades are still testable

Laravel's implementation goes a step further and allows you to define the base-class that the Facade "points" to.

This gives a developer the ability to "mock" a Facade - by switching the base-class out with a mock object.

In that sense, you can use them and still have testable code. This is where some confusion lies within the PHP community.

DI is often cited as making your code testable - they make mocking class dependencies easy. (Sidenote: Interfaces and DI have other important reasons for existing!)

Facades, on the other hand, are often cited as making testing harder because you can't "simply inject a mock object" into whatever code you're testing. However, as noted, you can in fact "mock" them.

Facade vs DI

This is where people get confused regarding whether Facades are an alternative to DI or not.

In a sense, they both add a dependency to your class - You can either use DI to add a dependency or you can use a Facade directly - FacadeName::method($param);. (Hopefully you are not instantiating any class directly within another :D ).

This does not make Facades an alternative to DI, but instead, within Laravel, does create a situation where you may decide to add class dependencies one of 2 ways - either using DI or by using a Facade. (You can, of course, use other ways. These "2 ways" are just the most-often used "testable way").

like image 33
fideloper Avatar answered Sep 19 '22 20:09

fideloper