Patrón de diseño Facade en Java

El patrón de diseño Facade simplifica la complejidad de un sistema mediante una interfaz mas sencilla. Mejora el acceso a nuestro sistema logrando que otros sistemas o subsistemas usen un punto de acceso en común que reduce la complejidad, minimizando las interacciones y dependencias.

Se trata de un patrón de diseño bastante útil en vista de que también desacopla los sistemas .

Facade

Cuales son las partes del patrón de diseño Facade

Dijimos que el patrón de diseño Facade dispone una interfaz simple y accesible a otros sistemas o subsistemas. De este modo simplifica la complejidad a los clientes externos exponiendo una interfaz más clara y un acceso unificado a estas funcionalidades haciendo más fácil su uso.

Tenemos entonces en este patrón tres partes:

  • El Cliente que accede al facade.
  • El Facade que accede al resto de funcionalidades y las unifica o simplifica.
  • El resto de funcionalidades / subsistemas, que están “detras” del facade.

Facade

Como se crea el patrón de diseño Facade en Java

Hablamos antes que el objetivo del patrón Facade es simplificar y unificar funcionalidades.

De este modo el cliente se olvida de entender la complejidad que hay del otro lado del facade.

Observa el siguiente ejemplo de un patrón Facade.

Pensemos en un teléfono móvil que debemos encender y para ello es necesario ejecutar varias acciones.

Facade

Definamos las diferentes funcionalidades de este ejemplo.


package patterns.facade;

public class Battery {

    public void on() {
        System.out.println("Battery on");
    }

    public void off() {
        System.out.println("Battery off");
    }
}


package patterns.facade;

public class CPU {

    public void bootLoad() {
        System.out.println("CPU boot loaded");
    }

    public void shutDown() {
        System.out.println("CPU shutdown");
    }
}

De esta interfaz MobileService implementaremos los servicios Wifi y GPS


package patterns.facade;

public interface MobileService {

    void start();
    void close();
}


package patterns.facade;

public class GPSService implements MobileService {
    @Override
    public void start() {
        System.out.println("GPS Service started");
    }

    @Override
    public void close() {
        System.out.println("GPS Service closed");
    }
}


package patterns.facade;

public class WifiSevice implements MobileService {
    @Override
    public void start() {
        System.out.println("WIFI Service started");
    }

    @Override
    public void close() {
        System.out.println("WIFI Service started");
    }
}

Nuestra clase que representa el Mobile.

El mobile tiene como atributos la bateria, la cpu y los servicios.


package patterns.facade;

import java.util.List;

public class Mobile {

    private final Battery battery;
    private final CPU cpu;
    private final List<MobileService> mobileServices;

    public Mobile(Battery battery, CPU cpu, List<MobileService> mobileServices) {
        this.battery = battery;
        this.cpu = cpu;
        this.mobileServices = mobileServices;
    }

    public CPU getCpu() {
        return cpu;
    }

    public Battery getBattery() {
        return battery;
    }

    public List<MobileService> getMobileServices() {
        return mobileServices;
    }
}

Definamos el facade que se encargará de simplificar todas la operaciones de encendido y de apagado del teléfono móvil.

Observa que el facade expondrá dos metodos “ON” , “OFF”.

Todo el resto ocurre dentro de facade y el cliente no necesita entender las acciones ni la secuencia para prender o apagar el teléfono.


package patterns.facade;

import java.util.Arrays;
import java.util.List;

public class MobileFacade {

    public Mobile on() {

        Battery battery = new Battery();
        battery.on();

        CPU cpu = new CPU();
        cpu.bootLoad();

        MobileService gps = new GPSService();
        gps.start();

        MobileService wifi = new WifiSevice();
        wifi.start();

        List<MobileService> mobileServices = Arrays.asList(gps, wifi);

        Mobile mobile = new Mobile(battery, cpu, mobileServices);

        return mobile;
    }

    public void off(Mobile mobile) {

        for(MobileService service :mobile.getMobileServices()) {
            service.close();
        }
        mobile.getCpu().shutDown();
        mobile.getBattery().off();
    }
}

Probamos el Facade desde nuestro cliente.


package patterns.facade;

public class ClientFacadePatternExample {

    public static void main(String[] args) {

        MobileFacade facade = new MobileFacade();
        Mobile mobile = facade.on();

        System.out.println("---------------");

        facade.off(mobile);
    }
}

La salida

--------------- ON ---------------
Battery on
CPU boot loaded
GPS Service started
WIFI Service started

--------------- OFF ---------------
GPS Service closed
WIFI Service started
CPU shutdown
Battery off

Conclusión

Cómo viste con el ejemplo este patrón es bastante simple de implementar y te ayudará a entregar a los clientes de tu servicio un acceso más sencillo unificando funcionalidades.

Puedes descargar este código en github

Hi! If you find my posts helpful, please support me by inviting me for a coffee :)

Ver también