Facades and How They Resolve

A facade is not a static class. Cache::get('catalog') lands in Facade::__callStatic(), which takes the string from the facade's protected getFacadeAccessor(), resolves it from the container, remembers the object and forwards the call. A bound closure reads each accessor here:

What four facades resolve toSQL
use Illuminate\Support\Facades\{Cache, DB, Event, Storage};
foreach ([Cache::class, DB::class, Event::class, Storage::class] as $f) {
    $accessor = (fn () => static::getFacadeAccessor())->bindTo(null, $f)();
    printf("%-8s %-10s %s\n", class_basename($f), $accessor, $f::getFacadeRoot()::class);
}
var_dump(Event::getFacadeRoot() === app('events'));
Event::fake();
echo Event::getFacadeRoot()::class, "\n";
Output
Cache    cache      Illuminate\Cache\CacheManager
DB       db         Illuminate\Database\DatabaseManager
Event    events     Illuminate\Events\Dispatcher
Storage  filesystem Illuminate\Filesystem\FilesystemManager
bool(true)
Illuminate\Support\Testing\Fakes\EventFake

The facade and app('events') are one object, and Event::fake() swaps the container entry, so later Event:: calls reach the fake (Mocks and Fakes). Prefixing any class with Facades\ makes a real-time facade: Facades\App\Reports\SalesReport::line() worked, generating storage/framework/cache/facade-<hash>.php. Facades hide the dependency that an injected LoggerInterface shows, so inject in domain services and keep facades for glue code.