Patrones de diseño: una guía rápida para el patrón de fachada.

El patrón de fachada a menudo se necesita cuando hay una gran cantidad de clases interdependientes o porque partes del código no están disponibles. Se utiliza como camuflaje para cubrir las complejidades de un sistema grande y, por lo tanto, proporciona una interfaz simple para el cliente. En otras palabras, es una clase de contenedor utilizada para ocultar los detalles de implementación.

El patrón de fachada se clasifica como un patrón de diseño estructural. Este patrón de diseño tiene que ver con la composición de clase y objeto. Los patrones estructurales de creación de clases utilizan la herencia para componer interfaces. Los patrones de objetos estructurales definen formas de componer objetos para obtener una nueva funcionalidad. [por Patrones de diseño explicados simplemente]

La imagen de arriba es el ejemplo perfecto de un patrón de Fachada. Un cliente en un restaurante ordena comida del menú, que probablemente se describe en media línea. La orden va a la cocina y la comida vuelve después de un rato. ¡Simple! El cliente no quiere saber quién cortará la carne durante cuánto tiempo se cocinará y quién lavará los platos después. El cliente solo quiere comer una comida sabrosa que cumpla con las expectativas. Por lo tanto, el menú sirve como fachada para facilitar al cliente al evitar las complejidades que provienen de la cocina o incluso las tareas que el camarero se asigna a través de este proceso.

Paso 1 - Palabras clave

Definir palabras clave es la receta secreta en esta serie de guías rápidas. Este método me ayudó a comprender realmente los patrones de diseño, codificarlos en mi mente y comprender las diferencias entre otros patrones de diseño.

  1. Simplificación: este es el objetivo de este patrón de diseño. Simplifica un sistema complicado.
  2. Restricción: La simplificación a menudo viene con un "costo sagrado", restricción. Al simplificar el código, restringimos a los clientes el acceso no autorizado. Por lo tanto, les impide cometer errores que serían difíciles de percibir en un subsistema complicado.

Existe una compensación entre la simplificación y la restricción. La simplificación excesiva de un sistema significa que el desarrollador está demasiado restringido, por lo tanto, menos libertad de la necesaria, lo que no siempre es bueno. El patrón de Fachada menos simplificado significa que hay demasiada libertad, lo que hace que el patrón de Fachada sea irrelevante. Encontrar el buen equilibrio es lo que hace un patrón de Fachada bueno, útil y efectivo.

Paso 2 - Diagrama

El diagrama también se basa en el ejemplo dado. Para simplificar este diagrama podemos separarnos en tres partes.

  1. Cliente: El cliente en este ejemplo es el cliente de un restaurante que quiere pedir comida.
  2. Fachada: su trabajo es proporcionar al cliente un acceso más simplificado a numerosos subsistemas interdependientes que se consideran complicados. En este ejemplo, el pedido de alimentos de un cliente requeriría una serie de llamadas a métodos cuidadosamente secuenciados de dos subsistemas diferentes (Waiter y Kitchen).
  3. Subsistemas: los subsistemas están ocultos para el cliente. Es posible que tampoco sean accesibles para el cliente. El cliente no puede jugar con ninguno de los subsistemas donde un simple cambio de código puede resultar fatal o incluso romper otras partes desconocidas del sistema. En este escenario, el camarero y la cocina tienen que hacer una serie de tareas. La tarea de un subsistema a veces depende de la tarea de otro. Por ejemplo, la cocina no puede preparar la comida si el camarero no lleva la orden a la cocina. El camarero no puede servir al cliente si la comida no está cocinada.

Paso 3 - Código por ejemplo

Sugeriría copiar el código clase por clase desde mi repositorio git "Andreas Poyias" o los fragmentos a continuación (en el orden proporcionado) y pegarlo en cualquiera de los editores C ++ en línea disponibles como c ++ shell, jdoodle, onlineGDB y ejecutar para observar la salida. Luego lea los comentarios o la descripción a continuación. Tómese su tiempo, léalo detenidamente (eso significa un minuto, ni menos ni más).

Subsistemas

En este ejemplo, los dos subsistemas son Waiter_Subsystem1 y Kitchen_Subsystem2. A primera vista, cada subsistema parece ser independiente, ya que pueden realizar ciertas tareas individualmente. ¿Pero es esto cierto?

#include 
usando el espacio de nombres estándar;
clase Waiter_Subsystem1
{
público:
  void writeOrder () {cout << "El camarero escribe la orden del cliente \ n";}
  void sendToKitchen () {cout << "Enviar pedido a la cocina \ n";}
  void serveCustomer () {cout << "¡Se atiende al cliente de Yeeei! \ n";}
};
clase Kitchen_Subsystem2
{
público:
    void prepareFood () {cout << "Cook food \ n";}
    void callWaiter () {cout << "Call Waiter \ n";}
    void washDishes () {cout << "Lave los platos \ n";}
};

Fachada: en este ejemplo, la clase Fachada trata sobre pedidos de comida en el restaurante. Para ejecutar un pedido de alimentos con éxito, confiamos en una secuencia específica de llamadas a métodos y una llamada depende de la anterior y así sucesivamente. La cocina no puede preparar la comida si el camarero no escribe la orden y la envía a la cocina. La clase Facade proporciona la tarea theorderFood al cliente para simplificarla y evitar cualquier uso indebido debido a la complejidad que existe.

clase Order_Facade
{
privado:
    Waiter_Subsystem1waiter;
    Kitchen_Subsystem2 cocina;
público:
    void orderFood ()
    {
        cout << "Una serie de llamadas interdependientes en varios subsistemas: \ n";
        waiter.writeOrder ();
        waiter.sendToKitchen ();
        cocina.prepareFood ();
        cocina.callWaiter ();
        waiter.serveCustomer ();
        cocina.lavadoPlatos ();
    }
};

Función principal
La función principal funciona como el cliente (igual que las guías anteriores). Es muy fácil para el cliente poder crear una instancia de Facade y llamar a una función para hacer su trabajo.

int main (int argc, char * argv [])
{
    // Simple para el cliente
    // no es necesario saber el orden o el
    // dependencias entre varios subsistemas.
    Orden_Fachada de fachada;
    fachada.orderFood ();
devuelve 0;
}
// Salida
// Una serie de llamadas interdependientes en varios subsistemas:
// Camarero escribe la orden del cliente
// Enviar orden a la cocina
//  Cocine los alimentos
// Llamar al camarero
// ¡Se atiende al cliente de Yeeei!
//  Lavar los platos

Hay algunos beneficios para el uso del patrón Facade y algunos puntos a tener en cuenta cuando se debe abordar Facade.

  • Facade define una interfaz de nivel superior que hace que el subsistema sea más fácil de usar al envolver un subsistema complicado.
  • Esto reduce la curva de aprendizaje necesaria para aprovechar con éxito el subsistema.
  • También promueve el desacoplamiento del subsistema de sus muchos clientes potenciales.
  • Por otro lado, si la Fachada es el único punto de acceso para el subsistema, limitará las características y la flexibilidad que puedan necesitar los "usuarios avanzados".

El próximo blog será una guía rápida del patrón de diseño de Observer. Es un patrón de comportamiento que es imprescindible para su repositorio de conocimientos. No olvides dar me gusta / aplaudir mi blog y seguir mi cuenta. Esto es para darme la satisfacción de haber ayudado a otros desarrolladores y empujarme a seguir escribiendo. Si hay un patrón de diseño específico sobre el que le gustaría aprender, avíseme para que pueda proporcionárselo en el futuro.

Otras guías rápidas sobre patrones de diseño:

  1. Patrones de diseño: una guía rápida de Abstract Factory.
  2. Patrones de diseño: una guía rápida para el patrón de puente.
  3. Patrones de diseño: una guía rápida para el patrón de construcción.
  4. Patrones de diseño: una guía rápida para el patrón de decorador.
  5. Patrones de diseño: una guía rápida para el patrón de fachada.
  6. Patrones de diseño: una guía rápida para el patrón de observador.
  7. Patrones de diseño: una guía rápida del patrón Singleton.