Introducción
El patrón de diseño Facade (Fachada) es un patrón estructural que proporciona una interfaz simplificada a un conjunto de interfaces en un subsistema. Este patrón define una interfaz de alto nivel que hace que el subsistema sea más fácil de usar.
Objetivos del Patrón Facade
- Simplificación: Proporcionar una interfaz simple para un subsistema complejo.
- Desacoplamiento: Reducir las dependencias entre los clientes y el subsistema.
- Facilidad de uso: Hacer que el subsistema sea más fácil de usar y entender.
Conceptos Clave
- Fachada: Una clase que proporciona una interfaz simplificada a un subsistema complejo.
- Subsistema: Un conjunto de clases que trabajan juntas para realizar una función específica.
- Cliente: La clase o conjunto de clases que utilizan la fachada para interactuar con el subsistema.
Estructura del Patrón Facade
Diagrama UML
+-----------------+ +-----------------+ | Cliente |------>| Fachada | +-----------------+ +-----------------+ | v +-----------------+ | Subsistema A | +-----------------+ | v +-----------------+ | Subsistema B | +-----------------+ | v +-----------------+ | Subsistema C | +-----------------+
Componentes
- Cliente: Interactúa con el subsistema a través de la fachada.
- Fachada: Proporciona métodos simplificados que llaman a los métodos del subsistema.
- Subsistema: Conjunto de clases que realizan las operaciones reales.
Ejemplo Práctico
Contexto
Imaginemos que estamos desarrollando un sistema de gestión de pedidos. Este sistema tiene varios subsistemas como el procesamiento de pagos, la gestión de inventario y el envío de productos. Queremos proporcionar una interfaz simplificada para que los clientes puedan realizar pedidos sin tener que interactuar directamente con cada subsistema.
Código
Subsistema de Procesamiento de Pagos
public class PaymentProcessor { public void processPayment(String paymentDetails) { System.out.println("Processing payment with details: " + paymentDetails); } }
Subsistema de Gestión de Inventario
public class InventoryManager { public void updateInventory(String product, int quantity) { System.out.println("Updating inventory for product: " + product + ", quantity: " + quantity); } }
Subsistema de Envío
public class ShippingService { public void shipProduct(String product, String address) { System.out.println("Shipping product: " + product + " to address: " + address); } }
Fachada
public class OrderFacade { private PaymentProcessor paymentProcessor; private InventoryManager inventoryManager; private ShippingService shippingService; public OrderFacade() { this.paymentProcessor = new PaymentProcessor(); this.inventoryManager = new InventoryManager(); this.shippingService = new ShippingService(); } public void placeOrder(String product, int quantity, String paymentDetails, String address) { paymentProcessor.processPayment(paymentDetails); inventoryManager.updateInventory(product, quantity); shippingService.shipProduct(product, address); System.out.println("Order placed successfully!"); } }
Cliente
public class Client { public static void main(String[] args) { OrderFacade orderFacade = new OrderFacade(); orderFacade.placeOrder("Laptop", 1, "Credit Card", "123 Main St, Anytown, USA"); } }
Explicación del Código
- Subsistemas:
PaymentProcessor
,InventoryManager
yShippingService
son clases que representan los subsistemas. - Fachada:
OrderFacade
proporciona una interfaz simplificada para realizar un pedido. Internamente, llama a los métodos de los subsistemas. - Cliente:
Client
utiliza la fachadaOrderFacade
para realizar un pedido sin tener que interactuar directamente con los subsistemas.
Ejercicio Práctico
Ejercicio
Imagina que estás desarrollando un sistema de gestión de viajes. Este sistema tiene varios subsistemas como la reserva de vuelos, la reserva de hoteles y la reserva de coches. Implementa una fachada que proporcione una interfaz simplificada para que los clientes puedan reservar un viaje completo.
Requisitos
- Subsistema de Reserva de Vuelos: Clase
FlightBooking
con un métodobookFlight(String flightDetails)
. - Subsistema de Reserva de Hoteles: Clase
HotelBooking
con un métodobookHotel(String hotelDetails)
. - Subsistema de Reserva de Coches: Clase
CarBooking
con un métodobookCar(String carDetails)
. - Fachada: Clase
TravelFacade
con un métodobookTrip(String flightDetails, String hotelDetails, String carDetails)
.
Solución
Subsistema de Reserva de Vuelos
public class FlightBooking { public void bookFlight(String flightDetails) { System.out.println("Booking flight with details: " + flightDetails); } }
Subsistema de Reserva de Hoteles
public class HotelBooking { public void bookHotel(String hotelDetails) { System.out.println("Booking hotel with details: " + hotelDetails); } }
Subsistema de Reserva de Coches
public class CarBooking { public void bookCar(String carDetails) { System.out.println("Booking car with details: " + carDetails); } }
Fachada
public class TravelFacade { private FlightBooking flightBooking; private HotelBooking hotelBooking; private CarBooking carBooking; public TravelFacade() { this.flightBooking = new FlightBooking(); this.hotelBooking = new HotelBooking(); this.carBooking = new CarBooking(); } public void bookTrip(String flightDetails, String hotelDetails, String carDetails) { flightBooking.bookFlight(flightDetails); hotelBooking.bookHotel(hotelDetails); carBooking.bookCar(carDetails); System.out.println("Trip booked successfully!"); } }
Cliente
public class Client { public static void main(String[] args) { TravelFacade travelFacade = new TravelFacade(); travelFacade.bookTrip("Flight 123", "Hotel ABC", "Car XYZ"); } }
Explicación del Código
- Subsistemas:
FlightBooking
,HotelBooking
yCarBooking
son clases que representan los subsistemas. - Fachada:
TravelFacade
proporciona una interfaz simplificada para reservar un viaje completo. Internamente, llama a los métodos de los subsistemas. - Cliente:
Client
utiliza la fachadaTravelFacade
para reservar un viaje sin tener que interactuar directamente con los subsistemas.
Conclusión
El patrón Facade es una herramienta poderosa para simplificar la interacción con subsistemas complejos. Al proporcionar una interfaz de alto nivel, este patrón reduce las dependencias y hace que el sistema sea más fácil de usar y mantener. En este módulo, hemos aprendido cómo implementar el patrón Facade y cómo puede ser aplicado en diferentes contextos.
Resumen
- Fachada: Proporciona una interfaz simplificada a un subsistema complejo.
- Subsistema: Conjunto de clases que realizan las operaciones reales.
- Cliente: Utiliza la fachada para interactuar con el subsistema.
- Ejemplo Práctico: Implementación de una fachada para un sistema de gestión de pedidos y un ejercicio práctico para un sistema de gestión de viajes.
Próximos Pasos
En el próximo módulo, exploraremos el patrón Flyweight, que es otro patrón estructural que ayuda a reducir el uso de memoria y mejorar el rendimiento en sistemas con gran cantidad de objetos similares.
Curso de Patrones de Diseño de Software
Módulo 1: Introducción a los Patrones de Diseño
- ¿Qué son los Patrones de Diseño?
- Historia y Origen de los Patrones de Diseño
- Clasificación de los Patrones de Diseño
- Ventajas y Desventajas de Usar Patrones de Diseño
Módulo 2: Patrones Creacionales
- Introducción a los Patrones Creacionales
- Singleton
- Factory Method
- Abstract Factory
- Builder
- Prototype
Módulo 3: Patrones Estructurales
Módulo 4: Patrones de Comportamiento
- Introducción a los Patrones de Comportamiento
- Chain of Responsibility
- Command
- Interpreter
- Iterator
- Mediator
- Memento
- Observer
- State
- Strategy
- Template Method
- Visitor
Módulo 5: Aplicación de Patrones de Diseño
- Cómo Seleccionar el Patrón Adecuado
- Ejemplos Prácticos de Uso de Patrones
- Patrones de Diseño en Proyectos Reales
- Refactorización Usando Patrones de Diseño
Módulo 6: Patrones de Diseño Avanzados
- Patrones de Diseño en Arquitecturas Modernas
- Patrones de Diseño en Microservicios
- Patrones de Diseño en Sistemas Distribuidos
- Patrones de Diseño en Desarrollo Ágil