Adapter

Allows objects with incompatible interfaces to collaborate.

Context

You want to use an external or legacy library whose API doesn't fit your domain's abstraction.

Problem
  • Modifying the external library is not an option.
  • Scattering inline adaptations pollutes the domain.
Solution

An Adapter implements the interface your client expects and translates calls to the existing API.

#Example in C#

// Your domain expects this interface
public interface IPaymentGateway { Task<bool> ChargeAsync(decimal amount, string currency); }

// Third-party SDK
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;
    }
}
When NOT to use it

If you control both parties, it's better to unify the interfaces and eliminate the adapter.

Tradeoffs
Pro Con
Isolates external dependency One more layer of indirection
Allows swapping providers Risk of leaking SDK concepts into the adapter

#Variants

  • Object Adapter (composition — the example above).
  • Class Adapter (multiple inheritance — limited in C# by the lack of multiple class inheritance).

#structural #gof #wrapper