Vous êtes sur la page 1sur 10

Patrones de Diseño Estructurales

Los patrones estructurales se centran en cómo se pueden combinar las clases y los objetos para formar estructuras más grandes y complejas. Este tipo de patrones es particularmente útil cuando queremos combinar la funcionalidad de varias bibliotecas de clases que se han desarrollado de forma independiente.

Los patrones estructurales de clases generalmente utilizan la herencia para componer interfaces que nos permiten establecer las relaciones entre clases. Los patrones estructurales asociados con objetos describen formas de componer los objetos para conseguir nueva funcionalidad

Clasificación Patrones Estructurales

Adapter: Convierte la interfaz que ofrece una clase en otra esperada por otra clase. Sirve de intermediario entre dos clases.

Bridge: Desacopla una abstracción de su implementación y les permite variar independientemente. Divide un componente complejo en dos jerarquías relacionadas, la abstracción funcional y la implementación interna.

Composite: Permite gestionar objetos complejos e individuales de forma uniforme. Desarrolla una forma flexible de crear jerarquías en estructura de árbol de una complejidad arbitraria, permitiendo a la vez que todos los elementos de la estructura funcionen con una interfaz uniforme.

Decorator: Extiende la funcionalidad de un objeto dinámicamente de tal modo que es transparente a sus clientes. Proporciona una forma flexible de introducir o eliminar funcionalidad de un componente sin modificar su apariencia externa o su función.

Facade:

Simplifica

los

accesos

a

un

conjunto

proporcionando una interfaz de comunicación.

de

objetos

relacionados

Flyweight: Reduce el número de objetos detallados de muy bajo nivel en un sistema usando la compartición de objetos de forma eficiente.

Proxy: Proporciona un objeto (representante) con el que controlamos el acceso a otro objeto.

Patrón Estructural Adapter

Descripción del patrón

Nombre:

Adaptador También conocido como Wrapper (encapsulador) Propiedades:

Tipo: estructural

Nivel: clase

Objetivo o Propósito:

Sirve de intermediario entre dos clases, convirtiendo las interfaces de una clase para que pueda ser utilizada por otra. Permite que cooperen clases que tienen interfaces incompatibles.

Aplicabilidad

Use el patrón Adapter cuando:

Se quiere usar una clase existente y su interfaz no concuerda con la que se necesita.

Deba realizar una traducción entre interfaces de varios objetos.

Un objeto tiene que actuar como intermediario para un grupo de clases, y solo es posible saber en tiempo de ejecución qué clase será utilizada.

Se quiere crear una clase reutilizable que coopere con clases no relacionadas o que no han sido previstas, es decir, clases que no tienen porque tener interfaces compatibles.

Es necesario usar varias subclases existentes, pero no resulta práctico adaptar su interfaz heredando de cada una de ellas (adaptador de objetos).

Estructura

Estructura Figure 1: Estructura patrón adapter Estructura en ingles Figure 2: Estructura patrón adapter Participantes

Figure 1: Estructura patrón adapter

Estructura en ingles

Figure 1: Estructura patrón adapter Estructura en ingles Figure 2: Estructura patrón adapter Participantes Objetivo:

Figure 2: Estructura patrón adapter

Participantes

Objetivo: Define la interfaz específica del dominio que usa el Cliente. Cliente: Colabora con objetos que se ajustan a la interfaz Objetivo.

Adaptable: Define una interfaz existente que necesita ser adaptada. Adaptador: Adapta la interfaz de Adaptable a la interfaz Objetivo

Variaciones del patrón

Un adaptador y múltiples adaptables. Dependiendo del diseño del sistema el adaptador puede añadir funcionalidad a todos los Adaptables a la vez.

Adaptadores no basados en interfaz. Se da en las situaciones en las que no se puede utilizar interfaces, por ejemplo, si se reciben componentes completos que no implementan ninguna interfaz.

Una capa de interfaz entre el invocador y el adaptador, y otra entre el adaptador y el adaptable. La capa entre el invocador y el adaptador permite que se puedan introducir fácilmente nuevos adaptadores en el sistema en tiempo de ejecución. Y entre el adaptador y el adaptable, hace que los adaptables sean cargados dinámicamente en tiempo de ejecución.

Consecuencias

El cliente es independiente de las clases finales que utiliza. Es posible utilizar la clase Adaptador para monitorizar que clases llaman a qué métodos de las clases finales.

Adaptador de Clase

La clase adaptadora puede redefinir y ampliar la interfaz de la clase adaptada. La clase adaptadora adapta una clase Adaptable a Objetivo, pero se refiere únicamente a una clase Adaptable concreta, por lo tanto no nos servirá para todas sus subclases.

Consecuencias

Adaptador de Objeto:

Permite que un mismo Adaptador funcione con muchos Adaptables.

La clase adaptadora puede utilizar todas las subclases de la clase adaptada, ya que tiene constancia de los objetos que instancia.

Hace que sea más difícil redefinir el comportamiento de Adaptable. Se necesitará crear una subclase de Adaptable y hacer que el Adaptador se refiera a la subclase en vez de a la clase Adaptable en sí.

Patrones relacionados

Bridge: Aunque son parecidos tienen objetivos diferentes ya que Bridge está pensado para separar una interfaz de su implementación, mientras que Adapter cambia la interfaz de un objeto existente.

Decorator:

Adapter

modifica

la

interfaz

de

un

objeto,

pero

mantiene

su

funcionalidad, Decorator permite que la interfaz sea igual pero mejora su funcionalidad.

Facade: Es una alternativa a Adaptador cuando en lugar de llamar a un solo objeto se necesita llamar a varios.

Proxy: Es similar a Adaptador en el sentido en que proporcionan una interfaz, con la diferencia en que Proxy ofrece la misma interfaz que la clase a la que se llama.

Diagrama ejemplo

Diagrama ejemplo Figure 3: : Ejemplo patrón adapter Código ejemplo AdaptadorFecha.java package Adapter; //Clase para

Figure 3: : Ejemplo patrón adapter

Código ejemplo

AdaptadorFecha.java

package Adapter;

//Clase para adaptar fechas USA (MM,DD,AAAA) a ES (DD/MM/AAAA) import java.util.*;

class AdaptadorFecha implements Fecha {

//Adapta el objeto de tipo Fecha USA FechaUS fus;

//constructor public AdaptadorFecha(FechaUS fus) {

this.fus = fus;

}

//métodos @Override public String toString() { StringTokenizer st = new StringTokenizer(fus.toString(), ","); String mm = st.nextToken();

;

String aaaa = st.nextToken();

return dd + "/" + mm + "/" + aaaa;

}

public int getAño() { return this.fus.getYear();

}

public void setAño(int año) {

}

public int getDia() {

;

 

;

}

public void setDia(int dia) { this.fus.setDay(dia);

}

public int getMes() {

 

;

}

public void setMes(int mes) { this.fus.setMonth(mes);

}

}

Fecha.java

package Adapter;

//Interface para manejar fechas en ES (DD/MM/AAAA) interface Fecha {

@Override public String toString();

public int getAño();

public void setAño(int año);

public int getDia();

public int getMes();

}

FechaUS.java

;

;

package Adapter;

//Clase para manejar fechas en USA (MM,DD,AAAA) import java.util.*;

class FechaUS { //atributos private int year; private int month; private int day;

//constructores public FechaUS(int month, int day, int year) { ;

this.month = month;

}

;

public FechaUS(String date) { StringTokenizer st = new StringTokenizer(date, ","); String mm = st.nextToken();

;

;

;

this.month = Integer.parseInt(mm);

this.year = Integer.parseInt(aa);

}

//métodos @Override public String toString() { return month + "," + day + "," + year;

}

public int getYear() { return this.year;

}

public void setYear(int year) { this.year = year;

}

public int getDay() { return this.day;

}

public void setDay(int day) { this.day = day;

}

public int getMonth() { return this.month;

}

public void setMonth(int month) { this.month = month;

}

}

Cliente.java

package Adapter; import java.io.*;

public class Cliente {

public static void main(String args[]) throws IOException {

BufferedReader entrada = new BufferedReader(new InputStreamReader(System.in)); Fecha fecha;

String f;

System.out.println("Introduce fecha en formato USA (MM,DD,AAAA): "); f = entrada.readLine(); fecha = new AdaptadorFecha(new FechaUS(f));

System.out.println(fecha.toString());

}

}

;