A primeira coisa que é necessário saber sobre esse padrão de projeto é que se lê Façade. A palavra é de origem francesa e, como bem sabemos, no inglês não existe C Cedilha, então, o mesmo foi omitido. Porém, a leitura segue a original, Façade.
Sabendo disso, o Facade, ou fachada, é um padrão de projeto estrutural simples de ser aplicado e por trás de sua fachada ele possui implementações práticas para simplificar várias etapas do desenvolvimento como desacoplamento de código e redução de dependências, simplificação de sua interface e encapsulamento do que é realmente necessário.
Tendo isso em mente, podemos partir para o que realmente importa.
Implementando… ↩
Vamos supor que desejamos cadastrar um cliente. Porém, o seu cadastro está dividido em partes.
Temos uma tabela chamada cliente e mais duas tabelas chamadas cliente_telefone e cliente_email. Essas duas últimas possuem chave estrangeira para a tabela cliente. Tendo isso em mente, temos um relacionamento de muitos para um onde um cliente pode possuir vários telefones e vários e-mails cadastrados. Cada uma dessas tabelas possui uma classe de model para manipular seus dados.
+--------------------------+
| Interface |
+--------------------------+
| ClienteTelefoneInterface |
+---------+----------------+
|
+---------+-------+
| Classe |
+-----------------+---------------+
| ClienteTelefone | |
+-----------------+ +---------+ +---------------+
| Classe | | Facade |
+---------+--------------+---------------+
| Cliente | | ClienteFacade |
+--------------+ +---------+ +---------------+
| Classe | |
+--------------+------------------+
| ClienteEmail |
+------+-------+
|
+------+-------------------+
| Interface |
+--------------------------+
| ClienteEmailInterface |
+--------------------------+
Estamos visualizando como as coisas devem funcionar na teoria, agora vamos aplicar tudo isso na prática.
A primeira coisa que vamos fazer é, implementar um pequeno bootstrap para que possamos incluir todas as nossas classes e interfaces na aplicação, vamos simplesmente deixar as coisas limpas. Atente-se ao diagrama acima, vamos criar um arquivo para cada tabela e, consequentemente, vamos incluir um de cada também em nosso simples bootstrap:
include_once ('Cliente.php');
include_once ('ClienteFacade.php');
include_once ('ClienteEmailInterface.php');
include_once ('ClienteTelefoneInterface.php');
include_once ('ClienteEmail.php');
include_once ('ClienteTelefone.php');
Agora sim, vamos começar pelas interfaces, são elas que determinarão o que será implementado na nossa classe e injetarão as dependências necessárias em nossa classe Cliente para que o facade rode perfeitamente.
Note que tanto as interfaces quanto as classes estão dentro do mesmo namespace e, por esse motivo, não foi necessário chamar os mesmos a partir do seu caminho absoluto, ou incluir os mesmos através do use.
Agora, vamos criar uma classe para injetar as dependências, essa classe se chamará apenas Cliente:
// Cliente.php
<?php
namespace Pattern;
class Cliente {
protected $clienteEmail;
protected $clienteTelefone;
public function __construct(ClienteEmailInterface $clienteEmail, ClienteTelefoneInterface $clienteTelefone) {
$this->clienteEmail = $clienteEmail;
$this->clienteTelefone = $clienteTelefone;
}
}
Note que a injeção de dependências ocorre a partir da interface, pois, caso exista mais de uma classe que implemente a mesma interface, você poderá passar como parâmetro a qualquer uma delas. Com isso desacopla o seu código e não cria uma dependência a partir de uma classe.
Você pode se perguntar: qual o motivo de eu ter criado uma classe para injetar as dependências se eu poderia fazer diretamente no facade? ↩
Simples, a ideia de um facade é que o mesmo seja limpo, fluido, sem dependências e fácil de implementar, criar uma camada apenas para injetar as dependências nos permite isso, assim, a implementação do facade se tornará simples, não dependerá de ninguém, ele próprio fará todo o serviço!!! 😉
E então, por fim, que venha o Facade .
// ClienteFacade.php
<?php
namespace Pattern;
class ClienteFacade {
protected $cliente;
public function __construct() {
$clienteEmail = new ClienteEmail();
$clienteTelefone = new ClienteTelefone();
$this->cliente = new Cliente($clienteEmail, $clienteTelefone);
}
public function addDados($email,$telefone) {
$this->clienteEmail->addEmail($email);
$this->clienteTelefone->addTelefone($telefone);
}
}
Nele, chamamos a classe que desejamos injetar no cliente e assim, criamos os métodos a partir do facade que serão implementados internamente.
Agora, vamos visualizar agora:
//index.php
include_once ('bootstrap.php');
use Pattern\ClienteFacade;
$facade = new ClienteFacade();
$facade->addDados('[email protected]','(11) 0000-0000');
Ufa, chegamos ao final… Com isso temos um facade implementado com sucesso, um código desacoplado, totalmente funcional. Para o programador que usará o mesmo, fica fácil! Agora, você meu chapa, que quer saber como as coisas funcionam, acaba de entender, em todas as camadas, sobre o funcionamento de uma facade . Espero que tenham gostado e até a próxima!!!
Leia também: Métodos encadeados no PHP, o $this da questão