← Back to list

Adapter / Wrapper Tasarım Deseni: Uyumsuz Arayüzleri Birleştirme

Structural Design Patterns Serisi

Meryem Çiftçi · 2026-05-21 18:15 · 0 claps · 2.3 min read
#software-design #design-patterns #software-engineering #clean-code #oop
Open on Medium ↗
Wiki topics: 🎵 · Music & Audio

Adapter / Wrapper Tasarım Deseni: Uyumsuz Arayüzleri Birleştirme

Structural Design Patterns Serisi

Elinde bir fişin var, ama prize girmiyor. Priz 3'lü, fiş 2'li. Elektriği değiştiremezsin, duvarı söküp priz de ekleyemezsin. Yapabileceğin tek şey: adaptör kullanmak.

Yazılımda da aynı sorunla karşılaşırsın. Hazır bir kütüphane var, işe yarıyor — ama senin sistemin onun arayüzünü tanımıyor. İşte tam bu noktada Adapter Pattern devreye girer.

Sorun: Arayüzler Uyuşmuyor

Diyelim ki bir e-ticaret sistemi geliştiriyorsun ve Stripe’ı entegre edeceksin. Sistemin şu arayüzü bekliyor:

public interface IPaymentGateway
{
    bool Pay(decimal amount, string currency);
    bool Refund(string transactionId);
}

Stripe SDK ise şöyle geliyor:

public class StripeService
{
    public StripeResult Charge(double amount, string curr, string apiKey) { ... }
    public bool Reimburse(string chargeId) { ... }
}

Üç sorun var aynı anda:

  • İsim farklı: PayCharge, RefundReimburse
  • Parametre sayısı farklı: Pay(decimal, string)Charge(double, string, string)
  • Tip farklı: decimaldouble

Stripe SDK’sını değiştiremezsin — kaynak koduna erişimin yok, NuGet paketi olarak geliyor. İstemci kodunu da bozmak istemiyorsun. Ne yapacaksın?

Çözüm: StripeAdapter

Adapter Pattern, uyumsuz iki arayüzü birbirine bağlayan bir ara katman oluşturur. İstemci sadece kendi bildiği arayüzü çağırır; adapter arka planda dönüşümü halleder.

public class StripeAdapter : IPaymentGateway
{
    private StripeService _stripe;
    private string _apiKey;
    public StripeAdapter(StripeService s, string key)
    {
        _stripe = s;
        _apiKey = key;
    }
    // Pay() → Stripe.Charge() dönüşümü
    public bool Pay(decimal amount, string currency)
    {
        var result = _stripe.Charge((double)amount, currency, _apiKey);
        return result.Success;
    }
    // Refund() → Stripe.Reimburse() dönüşümü
    public bool Refund(string transactionId)
        => _stripe.Reimburse(transactionId);
}

Dikkat et: StripeService'den kalıtım almıyoruz. Kompozisyon kullanıyoruz_stripe field'ında saklıyoruz. Bu, nesne tabanlı Adapter'ın temel yaklaşımıdır.

Kullanımı

// Stripe nesnesi oluştur
StripeService stripe = new StripeService();
// Adapter ile sar
IPaymentGateway odeme = new StripeAdapter(stripe, "sk_live_xxx");
// İstemci sadece IPaymentGateway biliyor
bool basarili = odeme.Pay(299.99m, "TRY");
// → Arka planda: Stripe.Charge(299.99, "TRY", apiKey) çalışır
// Yarın PayPal'a geçildi mi? Sadece yeni Adapter yaz
IPaymentGateway odeme2 = new PayPalAdapter(new PayPalService());
odeme2.Pay(299.99m, "TRY");
// → İstemci kodu HİÇ değişmedi!

İstemci IPaymentGateway tipinde referans tutuyor. Arkasında Stripe mi, PayPal mı, İyzico mu — bilmiyor, bilmesi de gerekmiyor. Open/Closed Principle tam burada sağlanıyor: yeni sağlayıcı = yeni Adapter, mevcut koda sıfır dokunuş.

Adapter ve Wrapper — Aynı Şey mi?

Sık karşılaşılan bir soru: “Adapter mı demeliyim, Wrapper mı?”

Wrapper, genel bir kavramdır. “Bir nesneyi sarıp kontrol etmek” anlamına gelir. Decorator, Proxy, Facade — hepsi birer Wrapper’dır.

Adapter ise Wrapper’ın belirli bir amaca hizmet eden özel halidir: uyumsuz arayüzleri birbirine bağlamak. Her Adapter bir Wrapper’dır, ama her Wrapper Adapter değildir.

Yani: “Adapter kullanıyorum” dediğinde wrapper kullandığını da söylemiş olursun. Ama tersi doğru değildir.

Ne Zaman Kullanmalısın?

  • Kaynak koduna erişemediğin bir kütüphaneyi entegre etmek istiyorsan
  • Farklı arayüzlü birden fazla sağlayıcıyı tek interface arkasında toplamak istiyorsan
  • Büyük bir API değişikliğinde eski istemcileri korumak için geçiş katmanı gerekiyorsa
  • Test ortamında bağımlılıkları MockAdapter ile değiştirmen gerekiyorsa
  • Legacy sistemi yeni mimariye adapte etmen gerekiyorsa

Avantajlar ve Dezavantajlar

Avantajlar

✅ Kaynak kodu değiştirmeden entegrasyon sağlar ✅ İstemci kodu sağlayıcıdan bağımsız kalır ✅ Yeni sağlayıcı eklemek mevcut kodu etkilemez (OCP)

Dezavantajlar

❌ Her sağlayıcı için ayrı Adapter sınıfı gerekir ❌ Basit durumlar için fazla katman ekleyebilir


메타데이터
post_id
a3a69bcbde3f
slug
adapter-wrapper-tasarım-deseni-uyumsuz-arayüzleri-birleştirme-a3a69bcbde3f
url
https://medium.com/@meryemmcftc/adapter-wrapper-tasar%C4%B1m-deseni-uyumsuz-aray%C3%BCzleri-birle%C5%9Ftirme-a3a69bcbde3f
canonical_url
https://medium.com/@meryemmcftc/adapter-wrapper-tasar%C4%B1m-deseni-uyumsuz-aray%C3%BCzleri-birle%C5%9Ftirme-a3a69bcbde3f
author_url
https://medium.com/@meryemmcftc
status
ok
fetched_at
2026-06-09 15:37:30