Facebook Pixel

Adapter

Your checkout service needs to charge a credit card. You integrate Stripe and write stripe_client.charge(amount_cents=5000, source_token="tok_abc") wherever a payment happens. Six months later the business adds PayPal. The PayPal SDK has a completely different method signature: paypal.execute_payment(amount_usd=50.0, payment_id="PAY-xyz"). Now every payment call site needs to know which vendor is in use and call the right method with the right arguments. Add a third processor and the problem compounds.

The deeper issue is that your business logic — charge the customer — is tightly coupled to a vendor SDK's interface. Each time you switch vendors, extend to new markets, or write a test that should not hit the real payment network, you have to change the code that should not care about which processor is underneath.

How the Adapter solves it

The Adapter wraps a third-party class behind your own interface. Your code always calls your interface. The adapter translates those calls into whatever the vendor SDK actually expects. Adding a new vendor means adding a new adapter class — nothing in your business logic changes.


The target is PaymentMethod — the interface your code depends on. The adaptees are StripeClient and PayPalClient — the third-party classes you cannot change. The adapters sit between them, translating every method call.

At runtime, CheckoutService calls charge on the adapter, which translates the call into whatever the underlying SDK actually expects.

Bad → Good

Without an adapter, every call site is aware of vendor details and cannot be easily swapped.

1# Bad: business logic is coupled directly to the Stripe SDK.
2# Switching to PayPal means changing every payment call site.
3class CheckoutService:
4    def __init__(self, stripe_client: StripeClient) -> None:
5        self._stripe = stripe_client
6
7    def complete_order(self, order: Order, token: str) -> None:
8        # This only works with Stripe. PayPal uses dollars, not cents,
9        # and expects a payment_id, not a source token.
10        charge = self._stripe.charge(
11            amount_cents=order.total_cents,
12            source_token=token,
13        )
14        order.mark_paid(charge.id)
Invest in Yourself
Your new job is waiting. 83% of people that complete the program get a job offer. Unlock unlimited access to all content and features.
Go Pro