- Introdução
- Explicação
- Uso Prático
- Criando Fachadas
- Imitando Fachadas (Mocking)
- Referências de Calsse Fachada
Fachadas fornecem uma interface "estática" para classes que estão disponíveis no container de serviço das aplicações. Laravel já vem com várias fachadas, e você provavelmente você tem as usado sem ao menos conhece-las! "Fachadas" do Laravel servem como "proxies" para classes subjacentes no container de serviços, fornecendo o benefício de uma sintaxe concisa e expressiva enquanto é mantida mais testável e flexível do que os métodos estáticos tradicionais.
Facades provide a "static" interface to classes that are available in the application's service container. Laravel ships with many facades, and you have probably been using them without even knowing it! Laravel "facades" serve as "static proxies" to underlying classes in the service container, providing the benefit of a terse, expressive syntax while maintaining more testability and flexibility than traditional static methods.
Ocasionalmente, você pode desejar criar sua própria fachada para sua aplicação e pacotes, então vamos explorar o conceito de desenvolvimento e uso dessas classes.
Nota: Antes de mergulhar no mundo das fachda, é fortemente recomendado que você se familiarize com o container de serviços do Laravel.
No contexto da aplicação Laravel, uma fachada é uma classe que forncece acesso para um objeto de um container. Toda a engenharia que faz este trabalho está na classe Facade
. As fachadas do Laravel, e qualquer outra fachada customizada que você criar, irá extender da classe base Facade
.
Sua classe fachada apenas necessita implementar um único método getFacadeAccessor
. É trabalho do método getFacadeAccessor
definir o que resolver a partir do container. A classe base Facade
fa uso do método-mágico __callStatic()
para adiar as chamadas da sua classe fachada para resolver o objeto.
Então, quando você faz a chamada de uma fachada como por exemplo: Cache::get
, o Laravel resolve a classe gerenciadora Cache de fora do container de serviços e chama o método get
da classe. Em termos técnicos, Fachadas Laravel são uma sintaxe conveniente para usar o container de serviços Laravel como um localizador de serviços.
No exemplo abaixo, a chamada é feita para o sistema de cache do Laravel. Ao olhar para este código, pode-se supor que o método estático get
é chamado na clsse Cache
.
In the example below, a call is made to the Laravel cache system. By glancing at this code, one might assume that the static method get
is being called on the Cache
class.
$value = Cache::get('key');
Contudo, se nos olharmos para classe Illuminate\Support\Facades\Cache
, você verá que lá não existe um método estático get
:
class Cache extends Facade {
/**
* Get the registered name of the component.
*
* @return string
*/
protected static function getFacadeAccessor() { return 'cache'; }
}
A classe Cache extende da classe base Facade
e define o método getFacadeAccessor()
. Lembre-se, o objetivo deste método é retornar o nome da ligação do container de serviços.
Quando um usuário faz referência a qualquer método estático na fachada Cache
, Laravel resolve a ligação cache
a partir do container de serviços e executa o método requisitado (neste caso, get
) contra esse objeto.
Então, nossa chamada Cache::get
pode ser re-escrita assim:
$value = $app->make('cache')->get('key');
Lembre-se, se você está usando uma fachada em um controlador que faz um de namespace, você precisará importar a classe da fachada no namespace. Todas as fachadas estão localizadas no namespace global:
<?php namespace App\Http\Controllers;
use Cache;
class PhotosController extends Controller {
/**
* Get all of the application photos.
*
* @return Response
*/
public function index()
{
$photos = Cache::get('photos');
//
}
}
Criar fachadas para sua própria aplicação ou pacote é simples. Você apenas precisa de três coisas:
- Uma ligação de container de serviços
- A classe Fachada.
- Uma configuração "alias" da fachada
Vamos dar uma olhada neste exemplo. Aqui, nos temos a classe definada como PaymentGateway\Payment
.
namespace PaymentGateway;
class Payment {
public function process()
{
//
}
}
Nos precisamos ser capazes de resolver esta classe a partir do container de serviços. Então, vamos adicionar a aligação para um fornecedor de serviços:
App::bind('payment', function()
{
return new \PaymentGateway\Payment;
});
Um ótimo lugar para registrar esta ligação seria criando um novo fornecerdor de serviços chamado PaymentServiceProvider
, e adicionar esta ligação ao método register
. Você pode então configurar para que o Laravel carregue seu fornecedor de serviços a partir do arquivo de configuração config/app.php
.
Após isto, nos podemos criar nosa própria classe fachada:
use Illuminate\Support\Facades\Facade;
class Payment extends Facade {
protected static function getFacadeAccessor() { return 'payment'; }
}
Finalmente, se quisermos, nos podemos adicionar um alias(apelido) para nossa fachada ao array aliases
no arquivos de configuração config/app.php
. Agora, nos podemos chamar o método process
na instância da classe Payment
.
Payment::process();
Classes no array aliases
não estão disponíveis em algumas instâncias por que PHP não irá tentar carregar automaticamente classes dom tipagens indefinidas. Se \ServiceWrapper\ApiTimeoutException
é apelidado de ApiTimeoutException
, a exeção catch(ApiTimeoutException $e)
fora do namespace \ServiceWrapper
nunca irá entrar na exeção, mesmo se uma for levantada. Um problema similar é encontrado em classes que tem tipagem para classes apelidadas (aliases). A única solução é não usar (aliasing, não apelidar classes) e usar
as classes que você deseja tipando-as no começo de cada arquivo que as requisita.
Teste unitário é importante aspecto do porque fachadas funcionam do jeito que são. Na verdade, testabilidade é a razão primária para fahadas sequer existam. Para mais informações, dê uma olhada na seção de documentação imitando fachadas
Abaixo você irá encontrar todas fachadas e suas classes subjacentes. Isto é uma ferramenta útil para rapidamente cavar mais fundo na documentação da API para uma determinada raiz da fachada. A chave ligação do container de serviços também é incluída aonde é aplicável.