Facade (padrón de deseño)

Os padróns de deseño dan unha solución probada e documentada a problemas que adoitan xurdir no desenvolvemento de software.O padrón de deseño **Facade** (*en galego: Fachada*) é un tipo de padrón estrutural.

dereita|450px

## Propósito 
O padrón fachada porporciona unha interface unificada de alto nivel para un conxunto de interfaces dun subsistema, facendo que este último sexa mais fácil de usar.

## Motivación 
A principal motivación do padrón fachada é a necesidade de estruturar un sistema en subsistemas menos complexos, minimizando deste modo as comunicacións e as dependencias entre eles.

## Aplicabilidade 
Aplicaremos o padrón fachada cando queiramos:

* Proporcionar unha interface simple para un subsistema complexo. O padrón fachada pode proporcionar unha vista simple do subsistema que resulta adecuado para a maioría dos clientes. Só aqueles que precisen mais personalización necesitarán ir máis alá da fachada.
* Desacoplar un sistema dos seus clientes e doutros subsistemas, facendoo mais portable, independente e reutilizable, reducindo as dependencias entre estes.
* Estruturar varios subsistemas en capas sendo as fachadas o punto de entrada en cada nivel.

## Estrutura 
A estrutura corresponde coa seguinte imaxe:

400px

## Participantes 
**Fachada** (*Facade*): coñece qué clases do subsistema son responsables ante unha petición, e delega as peticións dos clientes aos obxectos apropiados do subsistema.

**Subclases** (*ModuleA*, *ModuleB*, *ModuleC*...): implementan a funcionalidade do subsistema. Realizan o traballo solicitado pola fachada. Non coñecen a existencia da fachada.

## Colaboracións 
* Os clientes comunicanse co subsistema enviando peticións ao obxecto Fachada, o cal reenvía as peticións aos obxectos apropiados.
* Os clientes que usan a fachada non teñen que acceder directamente ós obxectos do subsistema, aínda que poderían facelo.

## Consecuencias 
As consecuencias máis importantes da aplicación deste padrón son:

* Redución do acoplamento entre clientes e subsistemas (conseguindo que os cambios das clases do sistema sexan transparentes aos clientes) e o illamento de cambios na implementación.
* Oculta aos clientes a complexidade do subsistema, facilitando o seu uso sen impedir o acceso ás clases do subsistema no caso no que sexa necesario.
* Facilita a división en capas e reduce dependencias de compilación.

## Vantaxes 
A principal vantaxa deste padrón consiste en que para modificar as clases dos subsistemas, só hai que realizar cambios na fachada, e os clientes poden permanecer alleos a elo. Ademais, os clientes non necesitan coñecer as clases que hai tras dela.

## Inconvenientes 
Se varios clientes necesitan acceder a subconxuntos diferentes da funcionalidade da que prové o sistema, poderían acabar usando só unha pequena parte da fachada, polo que sería interesante empregar varias fachadas máis específicas en lugar dunha única global.

## Padróns relacionados 
Un dos padróns relacionados co padrón fachada é o Singleton, dado que en determinadas ocasións as fachadas poden ser instancias únicas.

Os GRASP (*General Responsibility Assignment Software Patterns*) non son padróns de deseño, senón boas prácticas que guían o desenvolvedor para encontrar os padróns de deseño, que son mais concretos. Un dos padróns GRASP é un controlador que actúa como punto de entrada na capa lóxica, o que se pode comparar perfectamente có uso do padrón fachada.

## Usos coñecidos (problemas/solucións) 
**Problema**: Un cliente necesita acceder a parte da funcionalidade dun sistema mais complexo.
:* Definir unha interface que permita acceder unicamente a esa funcionalidade.

**Problema**: Existen grupos de tarefas moi frecuentes para as que se pode crear código mais sinxelo e lexible.
:* Definir unha funcionalidade que agrupe estas tarefas en funcións ou métodos sinxelos e claros.

**Problema**: Unha biblioteca é dificilmente lexible.
:* Crear un intermediario mais lexible.

**Problema**: Dependencia entre o código do cliente e a parte interna duna biblioteca.
:* Crear un intermediario e realizar chamadas á biblioteca só ou a través del.

**Problema**: Necesidade de acceder a un conxunto de APIs que poden ademais ter un deseño ineficiente.
:* Crear unha API intermedia, ben deseñada, que permita acceder á funcionalidade das demais.

**Problema**: Moitas clases cliente queren usar varias clases servidoras, e deben saber cal é exactamente a que lle proporciona cada servizo. O sistema volveríase moi complexo, porque habería que relacionar todas as clases cliente con todas e cada unha das clases servidoras.
:* Crear unha ou varias clases Fachada, que implementen tódolos servizos, de modo que ou tódolos clientes utilicen esa única clase, ou cada grupo de clientes use a fachada que mellor se axuste ás súas necesidades.

### Java 
O seguinte exemplo agocha un calendario cunha API complicada detrás dun padrón *Facade* más amigable. A saída é:

 *Data: 2011-05-15*
 *15 días despois: 2011-05-30*

```java
import java.util.Calendar;
import java.util.Formatter;
import java.util.GregorianCalendar;
 
/** Fachada */
public class FormatoData {
    private GregorianCalendar gcal;
 
    public FormatoData(String isodate_ymd) {
        String[] a = isodate_ymd.split("-");
        gcal = new GregorianCalendar(Integer.parseInt(a[0]), Integer.parseInt(a[1])-1, Integer.parseInt(a[2]));
    }

    public void sumarDias(int dias) { 
	gcal.add(Calendar.DAY_OF_MONTH, dias); 
    }

    public String toString() { 
	return String.format("%1$tY-%1$tm-%1$td", gcal);
    }
}

/** Cliente */
public class Cliente {
    public static void main(String[] args) {  
        FormatoData d = new FormatoData("2011-05-15");   
        System.out.println("Data: "+d);   
        d.sumarDias(15);   
        System.out.println("15 días despois: "+d);
    }
}
```

Nestoutro exemplo a fachada axuda a acceder comodamente a tódalas funcionalidades dun sistema de préstamo de libros, vídeos e música.

```java
/**
 * O padrón fachada estrutura un entorno de programación e reduce complexidade coa división en subsistemas.
 */

/**
 * Coa interface fachada, temos unha simple interface para acceder a clases diferentes.
 */
public class Fachada {
    private LibrariaLibros libros = new LibrariaLibros();
    private LibrariaVideo videos = new LibrariaVideo();
    private LibrariaMusica musica = new LibrariaMusica();
 
    public void buscarLibros() {
        libros.buscarLibros();
    }

    public void buscarMusica() {
        musica.buscarMusica();
    }

    public void buscarVideo() {
        videos.buscarVideo();
    }
} 
 
public class LibrariaLibros {
 
    public LibrariaLibros() { }
    public void buscarLibros() { /* ... */ }
}
 
public class LibrariaVideo {
   
    public LibrariaVideo() { }
    public void buscarVideo() { /* ... */ }
}
 
public class LibrariaMusica {
 
    public LibrariaMusica() { }
    public void buscarMusica() { /* ... */ }
}

public class Cliente {

    public static void main(String args[]){
        Fachada fachada = new Fachada();
        fachada.buscarLibros();
        fachada.buscarVideo();
        fachada.buscarMusica();
    }
}
```