- Proveer una interfaz unificada para un conjunto de interfaces en un subsistema. El patrón Facade define una interfaz de alto nivel que hace que el subsistema sea fácil de usar.
- Envolver un subsistema complicado con una interfaz simple.
Ejemplo de problema
Un segmento de la comunidad de clientes necesita una interfaz simplificada para toda la funcionalidad de un subsistema complejo.
Discusión
El patrón Facade discute el encapsulamiento de subsistema complejo dentro de un objeto de interfaz único. Esto reduce la curva de aprendizaje necesaria para aprovechar con éxito el subsistema. También promueve el desacoplamiento del subsistema de los potenciales clientes. Por otro lado, si el objeto de interfaz es el único punto de acceso al subsistema, éste limitará las características y la flexibilidad que los "usuarios avanzados" podrían necesitar.
El objeto Facade debería ser un intermediario o facilitador, bastante simple. No debería convertirse en un oráculo que lo sabe todo u objeto God.
Estructura
Facade toma un "acertijo envuelto en un enigma que a su vez esta envuelto en un misterio" e interpone un Wrapper que "doma" a la masa amorfa e inescrutable del software.
SubsystemOne y SubsystemThree no interactúan con los componentes internos de SubsystemTwo. Ellos utilizan al Facade SubsystemTwoWrapper. (En el ejemplo, la abstracción de más alto nivel).
Ejemplo
El patrón Facade define una interfaz única de alto nivel para un subsistema que lo hace más fácil de usar. Los clientes se encuentran con un Facade cuando ordenan productos de un catálogo. Un cliente llama por teléfono a un número y habla con un representante de atención al cliente. El representante actúa como Facade, proporcionando una interfaz para el departamento de pedidos, el departamento de facturación y el departamento de envíos.
Check list
- Identificar una interfaz que sea única y muy simple para el subsistema o componente.
- Diseñar una clase Wrapper que encapsule al subsistema.
- El objeto Facade/Wrapper captura la complejidad y las colaboraciones de los componentes para luego delegar a los métodos correspondientes.
- El cliente utiliza (está acoplado) solamente al Facade.
- Considerar si Facades adicionales aportarían un valor agregado.
Reglas de oro
- Facade define una nueva interfaz, mientras que Adapter utiliza una vieja interfaz. Se debe recordar que Adapter hace que dos interfaces existentes puedan trabajar juntas en lugar de crear una interfaz completamente nueva.
- Mientras Flyweight muestra como hacer abundantes objetos pequeños, Facade muestra cómo hacer que un único objeto represente a todo un subsistema.
- El patrón Mediator es similar a Facade en que extraen funcionalidad de clases existentes. Mediator abstrae/centraliza comunicaciones arbitrarias entre objeto "colegas". En forma rutinaria "agrega valor" y es conocido/referenciado por los objetos "colegas" En contraste, Facade define una interfaz a un subsistema, no agrega nueva funcionalidad y no es conocido por las clases del subsistema.
- Abstract Factory puede ser usado como una alternativa a Facade para ocultar clases de plataformas específicas.
- Los objetos Facade son a menudo implementados como Singletons porque sólo un objeto Facade es necesario.
- Adapter y Facade son ambos Wrappers. Pero ellos son diferentes tipos de Wrappers. La intención de Facade es producir una interfaz más simple y la intención de Adapter es para diseñar una interfaz existente. Mientras Facade envuelve múltiples objetos, Adapter envuelve sólo a uno.
Pregunta: ¿La manera de saber la diferencia entre el patrón Adapter y el patrón Facade es que el Adapter se ajusta a una clase y Facade puede representar a muchas?
Respuesta: No. Recordemos que, el patrón Adapter cambia la interfaz de una o más clases en una interfaz que el cliente espera. Mientras muchos ejemplos en libros de texto muestran al Adapter adaptando a un sola clase, se puede necesitar adaptar muchas clases para proporcionar la interfaz para la cual el cliente está codificado. Igualmente, Facade puede proporcionar una intertfaz más simplificada a un único objeto con una interfaz muy complicada. La diferencia entre los dos no está dada en la cantidad de clases que envuelven, sino en su intención.
Ejemplo de código en C#
using System;
class MainApp
{
public static void Main()
{
Facade facade = new Facade();
facade.MethodA();
facade.MethodB();
// Wait for user
Console.Read();
}
}
// "Subsystem ClassA"
class SubSystemOne
{
public void MethodOne()
{
Console.WriteLine(" SubSystemOne Method");
}
}
// Subsystem ClassB"
class SubSystemTwo
{
public void MethodTwo()
{
Console.WriteLine(" SubSystemTwo Method");
}
}
// Subsystem ClassC"
class SubSystemThree
{
public void MethodThree()
{
Console.WriteLine(" SubSystemThree Method");
}
}
// Subsystem ClassD"
class SubSystemFour
{
public void MethodFour()
{
Console.WriteLine(" SubSystemFour Method");
}
}
// "Facade"
class Facade
{
SubSystemOne one;
SubSystemTwo two;
SubSystemThree three;
SubSystemFour four;
public Facade()
{
one = new SubSystemOne();
two = new SubSystemTwo();
three = new SubSystemThree();
four = new SubSystemFour();
}
public void MethodA()
{
Console.WriteLine("\nMethodA() ---- ");
one.MethodOne();
two.MethodTwo();
four.MethodFour();
}
public void MethodB()
{
Console.WriteLine("\nMethodB() ---- ");
two.MethodTwo();
three.MethodThree();
}
}
2 comentarios:
Genial tu aporte!
interesantes comparaciones con los demás patrones.. gracias!
Muchas gracias por tu comentario y me alegro que te haya gustado el post.
Publicar un comentario
Muchas gracias por leer el post y comentarlo.