Adapter (padrón de deseño)

Adapter (tamén chamado wrapper ou adaptador) e un padrón de deseño estrutural que serve para transformar unha interface noutra compatible coa clase na que se quere utilizar.

 Motivación 
Algunhas veces unha clase deseñada para ser reusada non pode selo por que a súa interface non coincide coa interface específica que require unha determinada aplicación. Un adaptador permite as clases traballar conxuntamente con normalidade. O adaptador traduce as chamadas a súa interface en chamadas o interface orixinal, e a cantidade de código necesario para facelo é habitualmente pequeno. O adaptador é tamén responsable de transformar as chamadas.
Un exemplo disto sería que unha clase proporcionase valores booleanos na forma de cadeas “true” ou ”false” pero a clase dende a que se vai utilizar necesite eses valores en formato 1 e 0, desta forma a clase adaptadora realizaría o cambio.

 Aplicabilidade 
 Utilizarase este padrón cando se queira usar unha clase existente pero a interface non coincida coa que se necesita.
 Cando se queira crear unha clase reusable por clases non relacionadas ou imprevistas e que non teñen por que ter a mesma interface.
 Cando queiramos utilizar subclases existentes pero non sexa axeitado adaptar as súas interfaces. Neste caso pódese adaptar a súa interface por medio dunha clase adaptadora da interface do seu pai.

 Estrutura 
Temos dúas posibles opcións a hora de abordar este padrón:
miniatura|300px|Opción 1.
miniatura|300px|Diagrama secuencia Opción 1.
miniatura|300px|Diagrama obxectos Opción 1.
 Utilizar a herdanza múltiple, de forma que a clase adaptadora herde de ambas interfaces.
miniatura|300px|Opción 2.
miniatura|300px|Diagrama secuencia Opción 2.
miniatura|300px|Diagrama obxectos Opción 2.
 Substituír a herdanza múltiple por herdanza a clase obxectivo e unha referencia a clase adaptada.

 Participantes 
 Obxectivo: Define a interface específica que o cliente utiliza.
 Cliente: Colabora cos obxectos que conforman o obxectivo.
 Adaptado: Define unha interface existente que necesita ser adaptada.
 Adaptador: Adapta a interface existente a interface do obxectivo.

 Consecuencias 
 Clase Adaptadora
 So permite adaptar unha clase concreta, non permite adaptar unha clases e todas as súas subclases.
 Permite que o Adaptador redefina o comportamento do Adaptado, por ser unha subclase de Adaptable.
 Introduce un só obxecto, e non se necesita ningún punteiro de indireción adicional para obter o obxecto adaptado.
 Obxecto Adaptador
 Permite que un único Adaptador funcione con moitos Adaptados (co o Adaptado e todas as súas subclases). O Adaptador tamén pode engadir funcionalidade a todos os Adaptados a vez.
 Fai que sexa máis difícil redefinir o comportamento de Adaptado. Se necesitara crear unha subclase Adaptado e facer que o Adaptador se refira a subclase en vez de á clase Adaptado.
 O obxecto adaptador introduce un obxecto adicional, polo que a eficiencia da solución pode resentirse

 Código exemplo 
 Clase Adaptadora
public class Adaptado 
{
	public void peticionEspecifica()
	{
		System.out.println("Peticion especifica Herdanza Multiple...");
	}
}

public interface Obxetivo 
{
	public void peticion();
}

public class Adaptador extends Adaptado implements Obxetivo 
{
	public void peticion() 
	{
		peticionEspecifica();
	}
}

public class Cliente 
{
	public static void main (String[] arg)
	{
		Obxetivo Adr = new Adaptador();
		Adr.peticion();
	}
}

 Obxecto Adaptador
public class Adaptado 
{
	public void peticionEspecifica()
	{
		System.out.println("Peticion especifica Composicion...");
	}
}

public interface Obxetivo 
{
	public void peticion();
}

public class Adaptador implements Obxetivo
{
	private Adaptado _adaptado;

	public Adaptador (Adaptado a)
	{
		_adaptado = a;
	}

	public void peticion() 
	{
		_adaptado.peticionEspecifica();
	}
}

public class Cliente 
{
	public static void main (String[] arg)
	{
		Adaptado Ado = new Adaptado();
		Obxetivo Adr = new Adaptador(Ado);
		Adr.peticion();
	}
}

 Exemplo 
miniatura|300px|Exemplo de uso.
No seguinte exemplo queremos que unha clase cliente sexa capaz de comprobar o estado dunha rede de auga e de electricidade nun determinado punto.

Para a enquisa da electricidade dispoñemos dun método ao que poderíamos chamar directamente dende a comprobación da electricidade. No caso da auga só dispoñemos dun método getNivel, que nos da o nivel de auga nese momento. Deberemos comprobar nós se o nivel é o adecuado para determinar que a comprobación é certa.

É neste punto onde se introduce o padrón adaptador, para permitir a comprobación en base aos valores proporcionados pola outra clase.

 Notas 

 Véxase tamén 
 Outros artigos 
 Delegados. concepto relevante no padrón adaptador.
 Principio de inversión de dependencia.

Categoría:Padróns de deseño