Contracts Vs Facades in Laravel 5

The total Laravel 5 framework depends on many blocks of Interfaces, classes and other packaged versions that package developers have developed so far. Laravel 5 has happily used them and encourage you to do the same by following the SOLID principle and loose coupling. To master the Framework properly, you need to understand the core services that run Laravel 5. What are the main resources behind the scene? Basically, Contracts come in between regarding this scenario. Contracts are interfaces that provide this core services. Like ‘Illuminate\Contracts\Mail\Mailer’ defines the process of sending mails and doing that this interface simply pools in the implementation of mailer classes powered by the SwiftMailer. Now what are the ‘Facades’. Our chapter headline reads as ‘Contracts Vs Facades’. Do they have any similarity or relationship or anything else? Let me tell something about Facades first.
Facades are also interfaces. But it has a distinct difference with Contracts. First of all Facades are static interfaces that supply methods to the classes of service container. You have already seen a lot of Facades already. Remember ‘App’, ‘Route’, ‘DB’, ‘View’ etcetera. The main quality of Facades is, you can use it without type­hinting. Like in your ‘routes.php’ file you can write this code:

Route::bind('books', function ($id){
return App\Book::where('id', $id)-­>first();
});

and this ‘Route’ Facade directly resolves the contracts out of service container. Though Facades are static interfaces, they have more expressive syntaxes and provide more testability and flexibility than traditional static methodology. But the advantage of ‘Contracts’ is, you can define explicit dependencies for your classes and make your application more loosely coupled. Of course for most of the applications Facades work fine. But in some cases if you want to innovate something more, you need to use Contracts. How you could implement a contract? It is extremely simple and one example can illuminate the whole conception. Actually you have used it already! Suppose you have a ‘BookController’ through which you want to maintain a long list of your favorite books. To do that you need to store books in database. To do that you can bind your ‘Book’ Model in your ‘routes.php’ first, and then using resource you can do all kind of CRUD operations. In doing so, you need to log in.
Consider this code:

public function store(Request $request)
{
if (Auth::check()) {
// The user is logged in...
}
}

You can check whether the user is logged in or not. And depending on that you can only add your favorite books. For checking you use ‘Auth’ Facade. And it is fine. As long as you don’t want more decoupled state it works fine. But if you rather want to follow the SOLID principle and want a more decoupled state then instead of depending on concretion you love to adopt a more robust abstract approach. And in that case Contract comes to your rescue. Taylor Otwell himself keeps git­hub repositories on Contracts so you would better have a look around it. All of the Laravel Contracts live there:
https://github.com/illuminate/contracts.
Now let us go back to our previous topic. So we can either use our ‘Auth’ Facade. But try to understand one thing, when you use facade it assumes the framework and very tightly coupled with a concretion. But considering SOLID principle you want a decoupled state. What to do? Let us consider another scenario. We can inject our ‘Auth’ Facade through constructor like this and rewrite our whole code this way:

use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Auth\Guard as Auth;
class BooksController extends Controller
{
/**
* Display a listing of the resource.
*
* @return Response
*/
protected $auth;
public function __construct(Auth $auth) {
$this­->auth = $auth;
}
public function store(Request $request)
{
$this­->auth-­>attempt();
}
}

Now you might opine that it is much better as we have injected ‘Auth’ instance through our constructor. Yes, it is better than before but still it lacks the SOLID design principle. It depends upon a concrete class like:

namespace Illuminate\Auth;
use RuntimeException;
use Illuminate\Support\Str;
use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Contracts\Auth\UserProvider;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Illuminate\Contracts\Auth\Guard as GuardContract;
use Illuminate\Contracts\Cookie\QueueingFactory as CookieJar;
use Illuminate\Contracts\Auth\Authenticatable as UserContract;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
class Guard implements GuardContract {....}
//code is incomplete for brevity

As you see, when we use this line of code in our ‘BookController’: use Illuminate\Auth\Guard as Auth; We actually inject an instance based on concretion not abstraction. When we will unit test our code we will have to rewrite our codes. Moreover whenever you call any methods through this instance it is aware of your framework. But we need to make it completely unaware of our Framework and become loosely coupled. To do that we just have to change one line of code in our ‘BookController’.
Instead of that line of code:
use Illuminate\Auth\Guard as Auth;
We write this line of code:
use Illuminate\Contracts\Auth\Guard as Auth;
And that is it! Now our ‘Auth’ instance is completely loosely coupled. And now we can change that line of code in store() method:
if (Auth::check()) {
// The user is logged in...
}

to this line of code:
$this-­>auth­->attempt();
And it is done. Now your application has achieved more sophistication by following the SOLID design principle and becomes completely loosely coupled. Finally if check the interface Illuminate\Contracts\Auth\Guard what we see? Just have a look so that you can understand what happens behind the scene. The code of that interface is pretty big so for brevity we just cut the attempt() method out of it. The interface looks like this:

namespace Illuminate\Contracts\Auth;
interface Guard
{
/**
* Attempt to authenticate a user using the
given credentials.
*
* @param array $credentials
* @param bool $remember
* @param bool $login
* @return bool
*/
public function attempt(array $credentials = [], $remember = false, $login = true);
.....
}
//this code is incomplete

Now your code is not coupled to any vendor or even to Laravel. You are not compelled to follow a strict methodology by a concrete class. You can simply implement your own, alternative methodology out of any contract.
I hope this comparison between ‘contract’ and ‘facade’ makes sense.

https://leanpub.com/laravel5learneasy/embed


Advertisements

One thought on “Contracts Vs Facades in Laravel 5

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s