Секрети фасадів у Laravel: зручно, але чи завжди безпечно?

Секрети фасадів у Laravel: зручно, але чи завжди безпечно?

Фасади (Facades) — це зручна фішка Laravel:
замість оголошення залежностей просто пишемо Cache::get() або Log::info() — і все працює. Але що ж ховається за цією “магією”?

1. Як працюють фасади під капотом?

Фасад — це статична обгортка навколо об’єкта в Service Container.

Cache::get('key'); 

це лише скорочення для:

app('cache')->get('key');
// або через DI:
$cache->get('key');

Фасад просто делегує виклик до сервісу з контейнера. Він не є “справжнім” статичним методом — за ним стоїть Laravel Service Container.

2. У чому підводне каміння?

Фасади зручні, але:
• Погано тестуються — мокати Cache::shouldReceive() чи Mail::fake() не завжди інтуїтивно.
• Сховані залежності — важко зрозуміти, які саме сервіси використовує клас.
• Слабка інверсія керування (IoC) — не можна легко змінити реалізацію в рантаймі.

3. Коли краще використовувати dependency injection?

Завжди, коли:
• Пишете тестований, гнучкий код;
• Маєте кілька реалізацій інтерфейсу;
• Хочете зрозумілий список залежностей класу.

use Illuminate\Contracts\Cache\Repository as Cache;

class UserService 
{
    public function __construct(private Cache $cache) {}

    public function getUser(int $id)
    {
        return $this->cache->remember("user:$id", 60, fn() => User::find($id));
    }
}

4. Рефакторинг з фасаду на ін’єкцію залежності

Було:

class UserService 
{
    public function getUser(int $id)
    {
        return Cache::get("user:$id");
    }
}

Стало:

use Illuminate\Contracts\Cache\Repository as Cache;

class UserService 
{
    public function __construct(private Cache $cache) {}

    public function getUser(int $id)
    {
        return $this->cache->get("user:$id");
    }
}

Підсумок:
Фасади — це швидко і зручно. Але для зрілого коду з гнучкою архітектурою краще обирати ін’єкцію залежностей.

А як ви використовуєте фасади у своїх проєктах?
Поділіться думками в коментарях!

Залишити відповідь