Design Patterns - Facade

TLDR: El Facade (fachada) es un patrón que te permite simplificar sistemas complejos en una interfaz fácil de usar.


Este patrón de diseño estructural te provee una interfaz unificada de un set de interfaces en un subsistema. Esto siendo una definición a alto nivel que permite que ese subsistema sea más fácil de usar.

¿Porque necesitamos el Facade?

Imagina que estás trabajando en una empresa donde hay varios equipos de desarrollo, uno de los equipos, el equipo A, se encarga de realizar la estructura básica del proyecto que incluye el frontend y algunas API’s para la consulta de información. Otro de los equipos, el equipo B, se encarga de realizar una librería con un motor de cálculos, con un nivel de complejidad alto. Para poder usarlo se requiere inicializar varias clases en un orden en especifico, con varias configuraciones y funcionalidades.

El resultado de esta integración es que el equipo A tendrá en su capa de negocios una cantidad de clases altamente acopladas de la implementación del equipo B, haciendo difícil de mantener y comprender fácilmente. Aquí es donde es útil el patrón Facade, porque este te provee una interfaz de alto nivel con el que puedes aislar tu código de la complejidad de un subsistema que puede contener muchas partes, permitiendo que tu capa de lógica de negocios se vea más limpia y solo tenga lo necesario para funcionar, sin agregar más dependencias que las necesarias.

El Facade puede proveerte una funcionalidad limitada en comparación a trabajar con el subsistema directamente, pero la idea es que se incluya solamente las características que al cliente realmente le importa, y no tener que lidiar con docenas de características que la librería te provee.

Actualmente el patrón Facade es muy común en librerías Javascript, un ejemplo de esto es jQuery, en el que muchos sus métodos nos facilitan la implementación de una funcionalidad compleja. Un ejemplo claro es el uso de los métodos $(this).css() o $(this).animate(), que son dos simplificaciones a su implementación manual y te evitan tener que interactuar manualmente con las APIs del DOM.

En definición, ¿que es el patrón Facade?

Provee una interfaz simplificada para una librería, framework o cualquier grupo complejo de clases.

El problema en un ejemplo

Supongamos que tenemos una aplicación de prestamos bancarios online, dicha aplicación tiene un motor para el calculo de los prestamos bancarios a partir de varios criterios como lo son los Extractos bancarios, los informes de centrales de crédito y los antecedentes penales. Estos servicios tienen un subsistema que es complejo y posiblemente tome algo de tiempo en procesar la información.

En el siguiente ejemplo, realizaremos una clase para el manejo de los prestamos llamada Loans que será nuestra Facade , ya veremos porque es tan importante.

class Loans {
  constructor(name) {
    this.name = name;
  }

  ApplyFor(amount) {
    let result = "APROVADO";
    // Punto de acceso a multiples subsistemas
    let bankScore = new BankHistory().verify(this.name, amount);
    if (bankScore < 500) {
      result = "RECHAZADO";
    }

    let negativeReports = new CreditHistory().get(this.name);
    if (negativeReports.length > 0) {
      result = "RECHAZADO";
    }

    let criminalRecords = new PersonalProfile().check(this.name);
    if (criminalRecords.length > 0) {
      result = "RECHAZADO";
    }

    return `${this.name}, su préstamo por valor de ${amount} ha sido ${result}`;
  }
}

Como podemos ver, nuestra Facade Loans realiza todas las instancias de las clases del subsistema en un orden especifico y también se encarga de la manipulación de los objetos de una manera especifica. Esta Facade presenta una simple interfaz de cara al cliente con un simple método llamado ApplyFor, pero internamente toda su implementación tiene un nivel de complejidad.

Si vamos a utilizar esta Facade, solamente bastará con realizar lo siguiente:

let prestamos = new Loans("Juanito Alimaña");
console.log(prestamos.ApplyFor(1000000));
// Juanito Alimaña, su préstamo por valor de 1000000 ha sido RECHAZADO

Código completo del ejemplo: https://bit.ly/3bFIl9y

Estructura del patrón Facade

En este patrón encontramos varios componentes que interactuaran entre si.

  1. El Facade, en el ejemplo llamado Loans, es la clase que te provee un punto de acceso a una particular parte de una funcionalidad dentro de un subsistema. Esta clase sabrá como dirigir todas las peticiones del cliente y como operar todas las partes movibles.
  2. Los Facade Adicionales, son clases que pueden ser creadas para evitar la contaminación de un Facade con características poco relacionadas que posiblemente podría hacerlo otra estructura compleja.
  3. Los Subsistemas Complejos, consiste en docenas de varios objetos, que para hacer algo con verdaderamente significado para ti, tienes que indagar en las profundidades de los detalles de implementación del subsistema, como es la inicialización de objetos en un especifico orden, o el envío de la data apropiada en cierto formato, etc.
    Las clases del subsistema nunca se darán cuenta de la existencia de un Facade.
  4. El Cliente es la implementación del código que usa el Facade en vez de llamar y crear los objetos del subsistema directamente.

Conclusiones

  • El patrón de Facade te permite tener una interfaz limitada pero simple, hacia un sistema complejo, ayudando que la implementación sea rápida.
  • Este patrón es muy utilizado cuando quieres estructurar un subsistema en capas, ayudando a reducir el acoplamiento entre subsistemas, requiriendo solamente la comunicación a través de Facades.
  • Cuando se haga uso de este patrón, hay que estar atento de cualquier penalización en rendimiento que pueda agregar, para determinar si esa funcionalidad vale la pena su uso en comparación al nivel de abstracción que ha sido ofrecido.

Ejercicio

Se requiere que se construya una solución para integrar los subsistemas:

  • InstallServer
  • Database
  • ConfigWebsiteFiles
  • DnsServices

Se debe realizar una Facade que encapsule todas las funcionalidades de esos subsistemas para poder tener una implementación limpia y sencilla.

Estructura Inicial

Solución esperada

Recursos adicionales y bibliografia

Alexander Shvets - Dive into design Patterns

Erich Gamma, Richard Helm, Ralph Johnson, John M. Vlissides - Design Patterns Elements of Reusable Object-Oriented Software (1994)

Addy Osmani - Learning JavaScript Design Patterns (2012)

https://www.dofactory.com/javascript/facade-design-pattern

https://loredanacirstea.github.io/es6-design-patterns/#fa%C3%A7ade