Are Laravel facades dependencies?

风流意气都作罢 提交于 2019-12-07 12:51:43

问题


I have read that there should be not too much dependencies to one class. In one book, it states that 4 dependencies might be a sign that class might be doing too much.

Lets say I have written a class which uses 10 dependencies: 6 classes and 4 facades. Should I care only about those 6 classes and split them, or care about 4 facades too?

If somebody want to know how I get so many facades:

use Input;
use App;
use Session;
use Log;

Those all are needed often. I have heard question - why do I need App? To call a function:

App::setLocale('lt');

Some say that facades are not dependencies, also in here:

Polymorphism and dependency injection - too many dependencies

There are a bunch of different views on this matter (when does a class depend on something), but class dependencies are typically seen as what's passed into the constructor, i.e. what's needed for the class to be instantiated as an object.

I guess I can myself create a facade from a class and I will reduce the dependencies this way. But does this make much sense?

For example this article states - we should not use facades:

http://taylorotwell.com/response-dont-use-facades/

From it I understand that facades would be not that bad, but the bad thing is that class starts doing too many things.

I'm talking about Laravel 4, but probably same applies to Laravel 5 or other frameworks which use same. I just heard that Laravel 5 is not using as much facades as Laravel 4.

Update:

Also I would want to get such an argument so that I could use it with other people when discussing this topic. Like if I say - some guy (even with good stackoverflow profile) from the internet said to me that facades are bad, they are like global variables, they will instantly tell - this is not same as global, they are mockable, you should not care. Also they might tell, this is that guys opinion. So I want strong point to defend myself. So I could explain it like 2*2 = 4 and nobody ever could disagree. Or at least close to that.

Update:

If those are the dependencies, and I want to have about 4 dependencies max for one class, I have only one idea - to create grouped classes, would be like class tree. But I end up with many classes for small feature. Like from this 10 dependencies, if I want to have max 4 dependencies, I guess I would need 3-5 classes instead of 1. So if I have big project, you will have millions of small classes. Will it not look more complicated then? Like Laravel I see has lot of classes, while CodeIgniter has much less classes and looks simpler to read/follow, extend.


回答1:


Laravel facades are definitely dependencies, their intended use is for controllers, when building services and business logic you should try to make your dependencies as transparent as possible.

If you aim at achieving a SOLID implementation you will want to have all dependencies passed as params or in the class constructor.

Let's illustrate a little bit this abstractions:

before refactoring

Class PhotoService {

    protected $photosModel = null;

    public function getPhotos()
    { 
        $photos = Cache::get('photos');

        if (is_null($photos)) {
           return Photo::all();
        }
    }
}

still using facades, but solving other dependencies through IOC

Class PhotoService {

    protected $photosModel = null;

    public function __construct(PhotoInterface $photoModel) {
       $this->photosModel = $photoModel;
    }

    public function getPhotos()
    {
       $photos = Cache::get('photos');

       if (is_null($photos)) {
          return $this->photosModel->getPhotos();
       }
    }
}

solved through IOC

Class PhotoService {

    protected $photosModel = null;

    public function __construct(PhotoInterface $photoModel) {
       $this->photosModel = $photoModel;
    }

    public function getPhotos(CacheInterface $cache)
    {
       $photos = $cache->get('photos');

       if (is_null($photos)) {
          return $this->photosModel->getPhotos();
       }
    }
}

Best example in my point of view the case when externalizing your code, even when you share it between your own projects. It is way more easy for the new implementation to work if it is provided the full signature through an interface, rather than having to look through old code or tests for any facades.

I don't see any harm in using Facades in the controller though.

This kind of setup offers only advantages, between them:

  • the ability to switch cache strategies without headeaches
  • the ability to switch database types
  • the ability to switch features off by injecting a mock through ioc
  • encourages tdd by ease of implementation


来源:https://stackoverflow.com/questions/29294876/are-laravel-facades-dependencies

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!