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