Laravel Facade
Laravel Facade 는 라라벨 서비스 컨테이너에서 사용 가능한 클래스들에 대한 ‘정적인 인터페이스’를 제공하는 역할을 합니다. 서비스 컨테이너에 등록된 클래스들의 ‘정적 프록시’ 역할을 합니다. 뉴비 개발자에게 이 두 문장으로 파사드를 이해하기엔 부족한 느낌이 있었습니다. 제가 파사드를 이해한 흐름으로 설명하고자 합니다. 익숙한 단어들 위주로 공부해 보았습니다.
Proxy
![](https://www.stackhoarder.com/wp-content/uploads/2019/08/image-13.png)
Proxy 라는 개념 자체가 소프트웨어 공학에서 자주 등장하는 개념입니다. 컴퓨터를 공부하기 전 사용하면서 어디서 많이 봤다고 생각했는데 방화벽이 설정으로 웹 페이지 접속이 안되는 경우 저런 문구를 많이 보았습니다. 프록시라는 단어 자체도 익숙한데 개념은 익숙하지 않습니다. 프록시란 무엇일까요??
![](https://www.stackhoarder.com/wp-content/uploads/2019/08/800px-Proxy_concept_en.svg.png)
무언가( 프록시 프로그램, 서버, 클래스 등)의 대리인 입니다. ‘무언가’의 기능은 그대로 제공하면서 제어의 흐름만 프록시로 가져오는 역할을 합니다. 제어의 흐름을 프록시로 가져오면서 보호 받아야할 ‘무언가’ (실제 서버, 실제 구현체) 에 대한 이점을 취할 수 있게 됩니다. (위키 참조 – Proxy pattern) 포스팅을 위해 프록시에 대한 내용들을 찾아보았는데 다양한 곳에서 사용되고 양이 방대하여 이쯤에서 정리하고 넘어가겠습니다. 제어 흐름을 가져오는 대리인 정도로 기억하겠습니다.
Facade Pattern
![](https://www.stackhoarder.com/wp-content/uploads/2019/08/image-14-1024x440.png)
디자인 패턴 중에는 Facade Pattern 이 있습니다. Facade란 용어는 건물의 출입구로 이용되는 정면 외벽 부분 이라는 뜻입니다. 건축에서는 이 파사드를 가지고 디자인, 설계 등 다양한 요소를 파악한다고 합니다. 이와 비슷하게 소프트웨어 공학에서는 Facade Pattern 이란 복잡한 내부 설계를 간단한 인터페이스로 제공하는 것이라고 볼 수 있습니다. Proxy 패턴과 비슷하지만 Proxy는 기능을 그대로 제공하는 것에 비해 Facade 패턴은 복잡한 설계를 가공한 새로운 인터페이스를 만들어 제공합니다. (Proxy vs Facede 비교 정리)
Facade Pattern 에 대해 간략히 알아보았는데 사실 라라벨 Facade 와는 다른 점이 있습니다. 저같이 Facade Pattern 몰랐던 분은 디자인 패턴 하나를 익혔다고 생각하고 알고 계시던 분은 Facade Pattern 에 대한 개념은 잠시 접어두고 라라벨 Facade에 대해 알아보겠습니다. 이유는 아래서 언급하겠습니다.
Laravel Facade ??
라라벨 Facade 사용에 대한 다음 예제를 살펴보도록 하겠습니다. Cache 라는 서비스의 동적 메소드인 get(‘key’) 를 통해 데이터를 가져오고 싶습니다. 소스 코드로는 아래 처럼 구현할 수 있습니다.
<?php $cache = new \Illuminate\Filesystem\Cache(); $cache->get(); // Cache 는 Application 클래스의 register()에 등록(binding)되어 있다. // Cache 를 서비스 컨테이너에서 가져오고자 하면 다음과 같은 코드가 될 수 있다. // $this->app->make('cache')->get('key');
Facade 를 사용하면 동적 메소드를 정적 메소드 처럼 사용할 수 있습니다. Illuminate\Support\Facades 에 미리 등록된 Cache를 사용하면 위에 코드와 같이 동작합니다. Illuminate\Support\Facades 에 있는 Cache 를 사용함으로 \Illuminate\Filesystem\Cache 클래스명을 (현재는 심플하지만 복잡한 클래스명의 경우) 기억하지 않고 사용할 수 있다는 이점이 있습니다.
<?php use Illuminate\Support\Facades\Cache; Cache::get('key');
라라벨 Facade 는 서비스 컨테이너에 등록된 클래스들을 정적인 메소드 형태로 호출하게 해주는 Wrapper 클래스의 형태를 하고 있는 것을 알 수 있습니다.
Create Laravel Facade
라라벨 Facade 는 어떻게 만들까요? 추상 클래스 Facade를 상속받아 구현하면 됩니다. Facade 클래스를 열어보니 두 가지 메소드가 제일 먼저 보였습니다. resolved() 메소드는 말 그대로 서비스 컨테이너에서 서비스를 Resolving 하며 __callStatic() 에서는 해당 서비스 동적 메소드가 정적 메소드로 사용할 수 있도록 구성되어 있었습니다.
<?php namespace Illuminate\Support\Facades; abstract class Facade { //...// // resolved : 서비스 컨테이너 $app 에서 등록된 실제 서비스를 가져온다. $app->afterResolving('className') // getFacadeAccessor()에 서비스 이름을 리턴하여 사용한다. public static function resolved(Closure $callback) { static::$app->afterResolving(static::getFacadeAccessor(), function ($service) use ($callback) { $callback($service); }); } // __callStatic() 를 통해 서비스의 동적 메소드가 정적 메소드처럼 사용할 수 있게 한다. public static function __callStatic($method, $args) { $instance = static::getFacadeRoot(); if (! $instance) { throw new RuntimeException('A facade root has not been set.'); } return $instance->$method(...$args); } //...// }
Facade를 상속받는 구현체는 getFacadeAccessor() 에서 등록된 서비스 이름을 리턴해주면 Facade로 사용할 수 있습니다. 아래는 Cache Facade 객체인데 resolved 메소드를 참조하면 실제로는 $app->afterResolving(‘cache’)가 된다는 것을 알 수 있습니다.
<?php class Cache extends Facade { protected static function getFacadeAccessor() { return 'cache'; } }
Laravel Facade References
라라벨에서 이미 등록된 Facade 들은 config/app.php 에서 찾아볼 수 있습니다.
![](https://www.stackhoarder.com/wp-content/uploads/2019/08/image-15-820x1024.png)
Facade 란 명칭에 대해 (Laravel Facade != Facade Pattern)
지금까지 살펴본 라라벨 Facade는 뭔가 어색한 점이 있습니다. 디자인 패턴으로 다뤘던 Facade Pattern 과 매칭이 되지 않습니다. Facade Pattern 에서는 복잡한 설계를 가공한 새로운 인터페이스를 제공한다고 하였습니다. 하지만 필자는 라라벨 Facade는 서비스 컨테이너에서 서비스를 인스턴스화해서 같은 메소드를 제공하는 것이 Proxy Pattern 에 더 밀접한 관계가 있는 것으로 느껴졌습니다.
라라벨 Facade Naming 이란 키워드로 여러가지 서칭을 해보았는데 개발자 커뮤니티등 개발자들 사이에서 네이밍에 대한 논란이 있는 것을 알 수 있었습니다. Facade 란 이름이 혼란을 줄 여지가 있다고 이름을 변경을 요구하고 있는 경우를 찾아볼 수 있었습니다.
![](https://www.stackhoarder.com/wp-content/uploads/2019/08/image-16.png)
필자는 Facade Word 고유의 뜻 건물의 정면 이라는 개념으로 다가가는 것이 좋을 것 같다고 느꼈습니다. Facade 이라는 명칭은라라벨 프레임 워크를 이해하는데 방해가 되는 것은 분명합니다. 이미 명칭이 되어 온 것이라 지금 명칭을 새로 하는 것 또한 혼란을 가져올 것이기 때문에 필자는 좋은 방법이 떠오르지 않습니다. 프로그래밍에 있어 Naming 은 정말 중요한 것을 다시 한번 깨닫게 합니다. 이미 명칭된 것이기에 라라벨을 접하시는 분들은 이점을 고려해서 보셨으면 좋겠습니다.
TL;DR
- 라라벨 Facade 는 서비스 컨테이너에 등록되어 있는 서비스를 정적 메소드 형태로 사용해 줄 수 있게 한다.
- 라라벨 Facade 는 getFacadeAccessor() 를 구현하면 되며 config/app.php 에 라라벨 Facade 들을 확인해 볼수 있다.
- 라라벨 Facade 는 디자인 패턴 Facade Pattern 과는 개념이 다르다.