Секрети фасадів у 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"); } }
⸻
Підсумок:
Фасади — це швидко і зручно. Але для зрілого коду з гнучкою архітектурою краще обирати ін’єкцію залежностей.
А як ви використовуєте фасади у своїх проєктах?
Поділіться думками в коментарях!