Facade (padrón de deseño)
Este artigo precisa de máis fontes ou referencias que aparezan nunha publicación acreditada que poidan verificar o seu contido, como libros ou outras publicacións especializadas no tema. Por favor, axude mellorando este artigo. (Desde novembro de 2016.) |
Este artigo ou sección precisa dunha revisión do formato que siga o libro de estilo da Galipedia. Pode axudar a mellorar este artigo e outros en condicións semellantes. |
Este artigo ou sección precisa dunha revisión ortográfica e/ou de gramática (recurso útil: corrector ortográfico en liña de galego). Podes axudarte do revisor ortográfico, activándoo en: Preferencias → Trebellos → Navegación → Ortografía: Activar o revisor ortográfico. Colabora connosco neste artigo e noutros en condicións semellantes para que a Galipedia mellore e medre. |
Os padróns de deseño dan unha solución probada e documentada a problemas que adoitan xurdir no desenvolvemento de software.O padrón de deseño Facade (en galego: Fachada) é un tipo de padrón estrutural.
Propósito
[editar | editar a fonte]O padrón fachada porporciona unha interface unificada de alto nivel para un conxunto de interfaces dun subsistema, facendo que este último sexa mais fácil de usar.
Motivación
[editar | editar a fonte]A principal motivación do padrón fachada é a necesidade de estruturar un sistema en subsistemas menos complexos, minimizando deste modo as comunicacións e as dependencias entre eles.
Aplicabilidade
[editar | editar a fonte]Aplicaremos o padrón fachada cando queiramos:
- Proporcionar unha interface simple para un subsistema complexo. O padrón fachada pode proporcionar unha vista simple do subsistema que resulta adecuado para a maioría dos clientes. Só aqueles que precisen mais personalización necesitarán ir máis alá da fachada.
- Desacoplar un sistema dos seus clientes e doutros subsistemas, facendoo mais portable, independente e reutilizable, reducindo as dependencias entre estes.
- Estruturar varios subsistemas en capas sendo as fachadas o punto de entrada en cada nivel.
Estrutura
[editar | editar a fonte]A estrutura corresponde coa seguinte imaxe:
Participantes
[editar | editar a fonte]Fachada (Facade): coñece qué clases do subsistema son responsables ante unha petición, e delega as peticións dos clientes aos obxectos apropiados do subsistema.
Subclases (ModuleA, ModuleB, ModuleC...): implementan a funcionalidade do subsistema. Realizan o traballo solicitado pola fachada. Non coñecen a existencia da fachada.
Colaboracións
[editar | editar a fonte]- Os clientes comunicanse co subsistema enviando peticións ao obxecto Fachada, o cal reenvía as peticións aos obxectos apropiados.
- Os clientes que usan a fachada non teñen que acceder directamente ós obxectos do subsistema, aínda que poderían facelo.
Consecuencias
[editar | editar a fonte]As consecuencias máis importantes da aplicación deste padrón son:
- Redución do acoplamento entre clientes e subsistemas (conseguindo que os cambios das clases do sistema sexan transparentes aos clientes) e o illamento de cambios na implementación.
- Oculta aos clientes a complexidade do subsistema, facilitando o seu uso sen impedir o acceso ás clases do subsistema no caso no que sexa necesario.
- Facilita a división en capas e reduce dependencias de compilación.
Vantaxes
[editar | editar a fonte]A principal vantaxa deste padrón consiste en que para modificar as clases dos subsistemas, só hai que realizar cambios na fachada, e os clientes poden permanecer alleos a elo. Ademais, os clientes non necesitan coñecer as clases que hai tras dela.
Inconvenientes
[editar | editar a fonte]Se varios clientes necesitan acceder a subconxuntos diferentes da funcionalidade da que prové o sistema, poderían acabar usando só unha pequena parte da fachada, polo que sería interesante empregar varias fachadas máis específicas en lugar dunha única global.
Padróns relacionados
[editar | editar a fonte]Un dos padróns relacionados co padrón fachada é o Singleton, dado que en determinadas ocasións as fachadas poden ser instancias únicas.
Os GRASP (General Responsibility Assignment Software Patterns) non son padróns de deseño, senón boas prácticas que guían o desenvolvedor para encontrar os padróns de deseño, que son mais concretos. Un dos padróns GRASP é un controlador que actúa como punto de entrada na capa lóxica, o que se pode comparar perfectamente có uso do padrón fachada.
Usos coñecidos (problemas/solucións)
[editar | editar a fonte]Problema: Un cliente necesita acceder a parte da funcionalidade dun sistema mais complexo.
- Definir unha interface que permita acceder unicamente a esa funcionalidade.
Problema: Existen grupos de tarefas moi frecuentes para as que se pode crear código mais sinxelo e lexible.
- Definir unha funcionalidade que agrupe estas tarefas en funcións ou métodos sinxelos e claros.
Problema: Unha biblioteca é dificilmente lexible.
- Crear un intermediario mais lexible.
Problema: Dependencia entre o código do cliente e a parte interna duna biblioteca.
- Crear un intermediario e realizar chamadas á biblioteca só ou a través del.
Problema: Necesidade de acceder a un conxunto de APIs que poden ademais ter un deseño ineficiente.
- Crear unha API intermedia, ben deseñada, que permita acceder á funcionalidade das demais.
Problema: Moitas clases cliente queren usar varias clases servidoras, e deben saber cal é exactamente a que lle proporciona cada servizo. O sistema volveríase moi complexo, porque habería que relacionar todas as clases cliente con todas e cada unha das clases servidoras.
- Crear unha ou varias clases Fachada, que implementen tódolos servizos, de modo que ou tódolos clientes utilicen esa única clase, ou cada grupo de clientes use a fachada que mellor se axuste ás súas necesidades.
Java
[editar | editar a fonte]O seguinte exemplo agocha un calendario cunha API complicada detrás dun padrón Facade más amigable. A saída é:
Data: 2011-05-15 15 días despois: 2011-05-30
import java.util.Calendar;
import java.util.Formatter;
import java.util.GregorianCalendar;
/** Fachada */
public class FormatoData {
private GregorianCalendar gcal;
public FormatoData(String isodate_ymd) {
String[] a = isodate_ymd.split("-");
gcal = new GregorianCalendar(Integer.parseInt(a[0]), Integer.parseInt(a[1])-1, Integer.parseInt(a[2]));
}
public void sumarDias(int dias) {
gcal.add(Calendar.DAY_OF_MONTH, dias);
}
public String toString() {
return String.format("%1$tY-%1$tm-%1$td", gcal);
}
}
/** Cliente */
public class Cliente {
public static void main(String[] args) {
FormatoData d = new FormatoData("2011-05-15");
System.out.println("Data: "+d);
d.sumarDias(15);
System.out.println("15 días despois: "+d);
}
}
Nestoutro exemplo a fachada axuda a acceder comodamente a tódalas funcionalidades dun sistema de préstamo de libros, vídeos e música.
/**
* O padrón fachada estrutura un entorno de programación e reduce complexidade coa división en subsistemas.
*/
/**
* Coa interface fachada, temos unha simple interface para acceder a clases diferentes.
*/
public class Fachada {
private LibrariaLibros libros = new LibrariaLibros();
private LibrariaVideo videos = new LibrariaVideo();
private LibrariaMusica musica = new LibrariaMusica();
public void buscarLibros() {
libros.buscarLibros();
}
public void buscarMusica() {
musica.buscarMusica();
}
public void buscarVideo() {
videos.buscarVideo();
}
}
public class LibrariaLibros {
public LibrariaLibros() { }
public void buscarLibros() { /* ... */ }
}
public class LibrariaVideo {
public LibrariaVideo() { }
public void buscarVideo() { /* ... */ }
}
public class LibrariaMusica {
public LibrariaMusica() { }
public void buscarMusica() { /* ... */ }
}
public class Cliente {
public static void main(String args[]){
Fachada fachada = new Fachada();
fachada.buscarLibros();
fachada.buscarVideo();
fachada.buscarMusica();
}
}