Фасады Laravel зависят?

Я читал, что не должно быть слишком много зависимостей от одного класса. В одной книге говорится, что 4 зависимости могут быть признаком того, что класс может делать слишком много.

Допустим, я написал класс, который использует 10 зависимостей: 6 классов и 4 фасада. Должен ли я заботиться только об этих 6 классах и разделять их или заботиться и о 4 фасадах?

Если кто-то хочет знать, как я получаю так много фасадов:

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

Все они нужны часто. Я услышал вопрос - зачем мне приложение? Чтобы вызвать функцию:

App::setLocale('lt');

Некоторые говорят, что фасады не являются зависимостями, также здесь:

Полиморфизм и внедрение зависимостей - слишком много зависимостей

Существует множество различных мнений по этому поводу (когда класс от чего-то зависит), но зависимости класса обычно рассматриваются как то, что передается в конструктор, т.е. то, что необходимо для создания экземпляра класса как объекта.

Думаю, я могу сам создать фасад из класса и таким образом уменьшу зависимости. Но имеет ли это большой смысл?

Например, в этой статье говорится - мы не должны использовать фасады:

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

Из него я понимаю, что фасады были бы не так уж и плохи, но плохо то, что класс начинает делать слишком много вещей.

Я говорю о Laravel 4, но, вероятно, то же самое относится к Laravel 5 или другим фреймворкам, которые используют то же самое. Я только что слышал, что Laravel 5 использует не так много фасадов, как Laravel 4.

Обновление:

Также я хотел бы получить такой аргумент, чтобы я мог использовать его с другими людьми при обсуждении этой темы. Например, если я скажу - какой-то парень (даже с хорошим профилем stackoverflow) из интернета сказал мне, что фасады - это плохо, они как глобальные переменные, они сразу скажут - это не то же самое, что глобальные, они мокабельны, вы не должны забота. Также они могут сказать, что это мнение парней. Поэтому мне нужна сильная сторона, чтобы защитить себя. Так что я мог объяснить это как 2 * 2 = 4, и никто никогда не мог не согласиться. Или, по крайней мере, близко к этому.

Обновление:

Если это зависимости, и я хочу иметь максимум 4 зависимости для одного класса, у меня есть только одна идея - создавать сгруппированные классы, как дерево классов. Но я получаю много классов для небольших функций. Например, из этих 10 зависимостей, если я хочу иметь максимум 4 зависимости, я думаю, мне понадобится 3-5 классов вместо 1. Так что, если у меня большой проект, у вас будут миллионы маленьких классов. Не будет ли тогда это выглядеть сложнее? Как и в Laravel, я вижу, что у него много классов, в то время как у CodeIgniter гораздо меньше классов, и он выглядит проще для чтения/следования, расширения.


person Dariux    schedule 27.03.2015    source источник
comment
Они являются зависимостями. И то, как они отдаются тому, что нужно, — худший способ сделать это. Учитывая, что laravel предоставляет классу целый контейнер (App) с кучей хлама, некоторые его содержимое являются зависимостями. Остальное содержимое контейнера — бесполезная хрень, к которой вы можете получить доступ из любого места, потому что это ужасная реализация.   -  person PeeHaa    schedule 27.03.2015
comment
Из него я понимаю, что фасады были бы не так уж и плохи, вы не так поняли. У него почти те же проблемы, что и при использовании ключевого слова global. Также обратите внимание, что и Foo::bar(), и $app['foo']->bar() в основном одинаково дерьмовые. Связанный пост по теме: stackoverflow.com/questions/11923272/   -  person PeeHaa    schedule 27.03.2015
comment
@PeeHaa - в вашем примере темы - я вижу разницу: $ db жестко запрограммирован для класса, а фасады laravel можно сымитировать. Проблема с глобальными переменными Я вижу, что они могут конфликтовать, но у меня самой такой проблемы не было, потому что я не создаю свои фасады.   -  person Dariux    schedule 27.03.2015
comment
Это все еще скрытая зависимость. Вы не можете знать (посмотрев на сигнатуры методов), что у него есть определенная зависимость.   -  person PeeHaa    schedule 27.03.2015


Ответы (1)


Фасады Laravel определенно являются зависимостями, их предполагаемое использование — для контроллеров, при создании сервисов и бизнес-логики вы должны стараться сделать свои зависимости максимально прозрачными.

Если вы стремитесь к реализации SOLID, вам нужно, чтобы все зависимости передавались как параметры или в конструкторе класса.

Давайте немного проиллюстрируем эту абстракцию:

перед рефакторингом

Class PhotoService {

    protected $photosModel = null;

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

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

все еще используя фасады, но решая другие зависимости через 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();
       }
    }
}

решается через МОК

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();
       }
    }
}

Лучший пример, на мой взгляд, случай экстернализации вашего кода, даже когда вы делитесь им между своими собственными проектами. Новой реализации будет намного проще работать, если ей будет предоставлена ​​полная подпись через интерфейс, вместо того, чтобы просматривать старый код или тесты в поисках фасадов.

Однако я не вижу никакого вреда в использовании Facades в контроллере.

Этот тип установки предлагает только преимущества, между ними:

  • возможность переключения стратегий кэширования без головной боли
  • возможность переключения типов баз данных
  • возможность отключать функции, вводя макет через ioc
  • поощряет tdd простотой реализации
person Decebal    schedule 01.11.2015