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