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

```java
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

```java
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.