Adapter
Permite que objetos con interfaces incompatibles colaboren.
Contexto
Quieres usar una librería externa o legacy cuya API no encaja con la abstracción de tu dominio.
Problema
- Modificar la librería externa no es opción.
- Esparcir adaptaciones inline contamina el dominio.
Solución
Un Adapter implementa la interfaz que tu cliente espera y traduce las llamadas a la API existente.
#Ejemplo en C#
// Tu dominio espera esta interfaz
public interface IPaymentGateway { Task<bool> ChargeAsync(decimal amount, string currency); }
// SDK de terceros
public class StripeSdk
{
public Task<StripeResult> CreateCharge(int amountCents, string iso) => /* ... */ Task.FromResult(new StripeResult(true));
}
public record StripeResult(bool Ok);
public class StripeAdapter : IPaymentGateway
{
private readonly StripeSdk _sdk;
public StripeAdapter(StripeSdk sdk) => _sdk = sdk;
public async Task<bool> ChargeAsync(decimal amount, string currency)
{
var result = await _sdk.CreateCharge((int)(amount * 100), currency.ToUpperInvariant());
return result.Ok;
}
}Cuándo NO aplicarlo
Si controlas las dos partes, mejor unifica las interfaces y elimina el adaptador.
Tradeoffs
| Pro | Contra |
|---|---|
| Aísla la dependencia externa | Una capa de indirección más |
| Permite intercambiar proveedores | Riesgo de filtrar conceptos del SDK al adapter |
#Variantes
- Object Adapter (composición — el ejemplo anterior).
- Class Adapter (herencia múltiple — limitado en C# por la falta de herencia múltiple de clases).
#structural #gof #wrapper