파사드란
파사드는 애플리케이션의 서비스 컨테이너에서 사용 가능한 클래스에 대한 “정적” 인터페이스를 제공합니다. Laravel에는 거의 모든 기능에 접근할 수 있는 많은 파사드가 함께 포함되어 있습니다. Laravel의 파사드는 서비스 컨테이너 내의 실체 클래스에 대한 “정적 프록시”로 기능하며, 기존의 정적 메서드보다 테스트하기 쉽고 유연성을 유지하면서 간결하고 표현력이 풍부한 문법을 제공합니다. 모든 Laravel 파사드는Illuminate\Support\Facades 네임스페이스에 정의되어 있습니다.
파사드의 구조를 완벽하게 이해하지 못해도 문제 없습니다. 우선 사용법을 익히고 Laravel 학습을 계속해 나갑시다.
파사드의 구조
Laravel 애플리케이션에서 파사드는 컨테이너에서 객체로의 접근을 제공하는 클래스입니다. 이 구조는Facade 클래스에 의해 실현되고 있습니다. Laravel의 모든 파사드, 그리고 커스텀 파사드는 기저 클래스 Illuminate\Support\Facades\Facade를 상속합니다.
Facade 기저 클래스는 __callStatic() 매직 메서드를 사용해 파사드로의 호출을 컨테이너에서 해결된 객체로 위임합니다.
Cache 파사드를 임포트하고 있습니다. 이 파사드는 Illuminate\Contracts\Cache\Factory 인터페이스 구현으로의 접근을 프록시합니다. 파사드를 사용한 호출은 모두 Laravel의 캐시 서비스의 내부 인스턴스로 전달됩니다.
Illuminate\Support\Facades\Cache 클래스를 보면 정적 메서드 get은 존재하지 않습니다.
Cache 파사드는 기저 Facade 클래스를 상속하고, getFacadeAccessor() 메서드를 정의하고 있습니다. 이 메서드는 서비스 컨테이너의 바인딩 이름을 반환합니다. 사용자가 Cache 파사드의 정적 메서드를 호출하면 Laravel은 서비스 컨테이너에서 cache 바인딩을 해결하고, 그 객체에 대해 요청된 메서드(이 경우 get)를 실행합니다.
파사드를 사용하는 상황·사용하지 않는 상황
파사드의 장점
파사드에는 많은 장점이 있습니다. 수동으로 주입·설정해야 하는 긴 클래스명을 외우지 않고도 Laravel의 기능을 사용할 수 있는 간결하고 기억하기 쉬운 문법을 제공합니다. 또한 PHP의 다이내믹 메서드의 독자적인 사용법을 통해 테스트가 용이합니다.스코프 크리프에 주의한다
파사드를 사용할 때의 주된 위험은 클래스의 “스코프 크리프”입니다. 파사드는 사용하기 쉽고 주입을 필요로 하지 않으므로 클래스가 비대화되어 많은 파사드를 계속해서 사용하게 되기 쉽습니다. 의존성 주입을 사용하면 큰 생성자가 시각적인 피드백을 줍니다. 파사드를 사용하는 경우에는 클래스 크기에 주의하며 책임 범위를 좁게 유지합시다.파사드 vs. 의존성 주입
의존성 주입의 주요 장점 중 하나는 주입된 클래스의 구현을 교체할 수 있다는 것입니다. 이는 테스트 시에 유용합니다. 모의 객체나 스텁을 주입해 스텁에 대해 다양한 메서드가 호출되었음을 어서션할 수 있습니다. 진정으로 정적인 클래스 메서드는 일반적으로 모의 객체나 스텁으로 만들 수 없지만, 파사드는 다이내믹 메서드를 사용해 서비스 컨테이너에서 해결된 객체로의 메서드 호출을 프록시하기 때문에, 주입된 클래스 인스턴스를 테스트하는 것과 같은 방법으로 파사드를 테스트할 수 있습니다.Cache::get이 기대하는 인수로 호출되었음을 검증할 수 있습니다.
파사드 vs. 헬퍼 함수
파사드에 더해 Laravel은 뷰 생성, 이벤트 발생, 잡 디스패치, HTTP 응답 전송 등 일반적인 작업을 실행할 수 있는 “헬퍼” 함수를 제공합니다. 많은 헬퍼 함수는 대응하는 파사드와 같은 기능을 실행합니다.실시간 파사드
실시간 파사드를 사용하면 애플리케이션 내의 임의의 클래스를 파사드로 다룰 수 있습니다. 사용법을 설명하기 위해 먼저 실시간 파사드를 사용하지 않는 코드를 보겠습니다. 예를 들어Podcast 모델에 publish 메서드가 있다고 가정합니다. 다만 팟캐스트를 공개하려면 Publisher 인스턴스를 주입해야 합니다.
Publisher 인스턴스를 명시적으로 전달할 필요가 없어집니다. 실시간 파사드를 생성하려면 임포트할 클래스의 네임스페이스에 Facades라는 프리픽스를 붙입니다.
Facades 프리픽스 뒤에 나타나는 인터페이스 또는 클래스명 부분을 사용해 서비스 컨테이너에서 퍼블리셔의 구현이 해결됩니다.
파사드의 테스트
파사드를 테스트하려면shouldReceive 메서드를 사용합니다. 이를 통해 Mockery의 모의 객체 인스턴스가 반환됩니다. 파사드는 실제로 서비스 컨테이너에 의해 해결·관리되기 때문에 일반적인 정적 클래스보다 훨씬 테스트하기 쉽습니다.
| 메서드 | 설명 |
|---|---|
shouldReceive('method') | 메서드가 호출될 것을 기대한다 |
once() | 한 번만 호출될 것을 기대한다 |
times(n) | n번 호출될 것을 기대한다 |
with(args) | 특정 인수로 호출될 것을 기대한다 |
andReturn(value) | 지정한 값을 반환한다 |
andReturnNull() | null을 반환한다 |
주요 파사드 목록
자주 사용하는 파사드와 그 실체 클래스, 서비스 컨테이너의 바인딩 이름 대응표입니다.| 파사드 | 클래스 | 바인딩 |
|---|---|---|
App | Illuminate\Foundation\Application | app |
Auth | Illuminate\Auth\AuthManager | auth |
Cache | Illuminate\Cache\CacheManager | cache |
Config | Illuminate\Config\Repository | config |
Cookie | Illuminate\Cookie\CookieJar | cookie |
Crypt | Illuminate\Encryption\Encrypter | encrypter |
DB | Illuminate\Database\DatabaseManager | db |
Event | Illuminate\Events\Dispatcher | events |
File | Illuminate\Filesystem\Filesystem | files |
Gate | Illuminate\Contracts\Auth\Access\Gate | — |
Hash | Illuminate\Contracts\Hashing\Hasher | hash |
Http | Illuminate\Http\Client\Factory | — |
Log | Illuminate\Log\LogManager | log |
Mail | Illuminate\Mail\Mailer | mailer |
Notification | Illuminate\Notifications\ChannelManager | — |
Queue | Illuminate\Queue\QueueManager | queue |
RateLimiter | Illuminate\Cache\RateLimiter | — |
Redirect | Illuminate\Routing\Redirector | redirect |
Request | Illuminate\Http\Request | request |
Route | Illuminate\Routing\Router | router |
Schema | Illuminate\Database\Schema\Builder | — |
Session | Illuminate\Session\SessionManager | session |
Storage | Illuminate\Filesystem\FilesystemManager | filesystem |
URL | Illuminate\Routing\UrlGenerator | url |
Validator | Illuminate\Validation\Factory | validator |
View | Illuminate\View\Factory | view |
다음 단계
Contracts(계약)
파사드와 짝을 이루는 Contracts의 개념과 구분 사용을 배웁니다.