Adapter deseninin TypeScript, React ve Node.js örnekleriyle uyumsuz arayüzleri nasıl birbirine bağladığını ve entegrasyonları ile eski kodu nasıl modernize ettiğini öğrenin.
December 19, 2025 (3mo ago) — last updated February 10, 2026 (2mo ago)
Adapter Deseni: TypeScript, React ve Node.js Örnekleri
Adapter deseninin TypeScript, React ve Node.js örnekleriyle uyumsuz arayüzleri nasıl birbirine bağladığını ve entegrasyonları ile eski kodu nasıl modernize ettiğini öğrenin.
← Back to blog
Adapter Pattern: TypeScript, React & Node.js Örnekleri
Özet: Adapter deseninin TypeScript, React ve Node.js içinde uyumsuz arayüzleri nasıl birbirine bağladığını gerçek dünya örnekleriyle öğrenin.
Giriş
Hiç sisteminizin geri kalanıyla uymayan, ama gayet iyi çalışan bir kütüphane veya eski bir modülünüz oldu mu? Bu, bir Avrupa adaptörünü Kuzey Amerika prizine takmaya çalışmak gibi — ikisi çalışır ama arayüzleri uyuşmaz. Adapter deseni, bir arayüzü başka bir arayüze çevirerek mevcut kodu değiştirmeden yeniden kullanmanızı sağlar.
Bu kılavuz deseni açıklar, TypeScript ve React örnekleri gösterir ve geri çağrı tabanlı modülleri modernize eden bir Node.js adaptörünü sergiler. Entegrasyonları temizlemek ve test edilebilirliği artırmak için hemen uygulayabileceğiniz pratik tekniklere odaklanır.
Neden Adapter Deseni Önemlidir
Adapter deseni, uyumsuz bir nesneyi sarıp kodunuzun beklediği arayüzü açığa çıkaran yapısal bir desendir. İlk olarak Gang of Four tarafından 1994'te belgelenmiştir1. Adaptörler, üçüncü taraf API'lerini entegre etmek, eski kodu modernize etmek ve farklı veri kaynaklarını birleştirmek için çok önemlidir.
Adaptörlerin yardımcı olduğu yaygın senaryolar:
- Farklı veri şekilleri döndüren üçüncü taraf API'lerini entegre etmek.
- Eski callback (geri çağrı) API'lerini async/await ile çalışacak şekilde modernize etmek.
- Birden çok veri kaynağını UI bileşenleri için tek bir arayüze birleştirmek.
Bir adaptör kullanmak iş mantığını temiz ve dış sistemlerden bağımsız tutar.
Adapter Desenine Genel Bakış
| Kavram | Açıklama |
|---|---|
| Tür | Yapısal |
| Birincil amaç | Uyumsuz arayüzlere sahip nesnelerin birlikte çalışabilmesini sağlamak |
| Temel fikir | Adaptee'yi sarıp hedef arayüzü açığa çıkarmak |
| Çözülen ana problem | Mevcut sınıfları kaynak kodlarını değiştirmeden yeniden kullanmak |
| Yaygın kullanım durumları | Üçüncü taraf kütüphaneler, eski kod, birden çok veri kaynağı |
Yapı ve Roller
Desenin dört rolü vardır:
- İstemci — belirli bir arayüze ihtiyaç duyan kod.
- Hedef Arayüz — İstemci'nin beklediği sözleşme.
- Adaptee — gerekli işlevselliğe sahip uyumsuz sınıf veya modül.
- Adaptör — Hedef'i uygular ve ihtiyaç duyulduğunda çağrıları Adaptee'ye delege ederek çeviri yapar.
İki yaygın adaptör stili:
- Nesne adaptörü (bileşim): Adaptör, Adaptee örneğini tutar. Bu en esnek yaklaşımdır.
- Sınıf adaptörü (kalıtım): Adaptör, Adaptee'den miras alır ve Hedef'i uygular. Bu çoklu kalıtım gerektirir ve modern JavaScript/TypeScript'te daha az yaygındır.
Pratik Örnek: TypeScript + React
Bir panonun iki farklı hizmetten kullanıcı profilleri aldığını ve bu hizmetlerin farklı yanıt şekillerine sahip olduğunu hayal edin. Bir adaptör olmadan bileşenler koşullu mantarla dolmaya başlar.
Uyumsuz API şekilleri
// Data from UserServiceA
interface UserA {
userId: number;
fullName: string;
emailAddress: string;
}
// Data from UserServiceB
interface UserB {
id: string;
name: string;
contact: {
email: string;
};
}
Uygulamamızın beklediği hedef arayüz
interface UnifiedUser {
id: string;
name: string;
email: string;
}
TypeScript adaptörleri
// Adapter for UserServiceA
function adaptUserA(userA: UserA): UnifiedUser {
return {
id: userA.userId.toString(),
name: userA.fullName,
email: userA.emailAddress,
};
}
// Adapter for UserServiceB
function adaptUserB(userB: UserB): UnifiedUser {
return {
id: userB.id,
name: userB.name,
email: userB.contact.email,
};
}
Dönüşümlerin merkezileştirilmesi bileşenleri temiz ve dayanıklı tutar. Bir API bir alanın adını değiştirirse, sadece adaptör değişir.
Birleşik veriyi tüketen React bileşeni
interface UserProfileProps {
user: UnifiedUser;
}
const UserProfile: React.FC<UserProfileProps> = ({ user }) => {
return (
<div>
<h2>{user.name}</h2>
<p>ID: {user.id}</p>
<p>Email: {user.email}</p>
</div>
);
};
Bu bileşen tek, öngörülebilir bir şekle dayanır; bu da test etmeyi ve yeniden kullanımı basitleştirir.
Örnek: Callback Tabanlı Bir Node.js Modülünü Modernize Etme
Eski modüller genellikle hata-öncelikli callback'ler kullanır. Kararlı bir modülü değiştirmek yerine, Promise tabanlı bir API açığa çıkaran bir adaptör oluşturun.
Eski adaptee (değiştirmeyin)
// legacyFileProcessor.js
const fs = require('fs');
class LegacyFileProcessor {
processFile(filePath, callback) {
fs.readFile(filePath, 'utf8', (err, data) => {
if (err) {
return callback(err, null);
}
const processedContent = data.toUpperCase();
callback(null, processedContent);
});
}
}
module.exports = LegacyFileProcessor;
Promise döndüren adaptör
// FileProcessorAdapter.js
const LegacyFileProcessor = require('./legacyFileProcessor');
class FileProcessorAdapter {
constructor() {
this.legacyProcessor = new LegacyFileProcessor();
}
processFile(filePath) {
return new Promise((resolve, reject) => {
this.legacyProcessor.processFile(filePath, (err, data) => {
if (err) return reject(err);
resolve(data);
});
});
}
}
module.exports = FileProcessorAdapter;
Bu, Node'un util.promisify davranışını taklit eder ancak adaptasyon mantığını açık ve test edilebilir tutar3.
Uygulama kodunda adaptörün kullanımı
const FileProcessorAdapter = require('./FileProcessorAdapter');
const fileProcessor = new FileProcessorAdapter();
async function handleFileProcessing() {
try {
console.log('Processing file with modern async/await...');
const content = await fileProcessor.processFile('my-file.txt');
console.log('Processed Content:', content);
} catch (error) {
console.error('An error occurred:', error);
}
}
handleFileProcessing();
Bu, eski kodu ellemeden geri kalan kod tabanınıza modern bir arayüz sağlar.
Ne Zaman Adaptör Kullanılmalı
İki bileşen arayüzleri farklı olduğu için doğrudan iletişim kuramıyorsa adaptör kullanın. Tipik senaryolar:
- Girdi veya çıktıları modellerinizle uyuşmayan üçüncü taraf bir API'yi entegre etmek.
- Eski callback API'lerini async/await ile çalışacak şekilde sarmak.
- Farklı formatlara sahip birden çok veri kaynağını her kaynak için bir adaptör oluşturarak desteklemek.
Adaptör kullanılmaması gereken durumlar:
- Her iki sistemi de kontrol ediyorsanız ve küçük bir refaktör uyumsuzluğu çözecekse, doğrudan refaktörlemeyi tercih edin.
- Amacınız karmaşık bir alt sistemi basitleştirmekse, yerine Facade (Cephe) düşünün. Facade basitleştirilmiş, yüksek seviyeli bir giriş sunarken; Adapter yalnızca uyumluluğa odaklanır.
Hızlı karar kontrol listesi
| Durum | Adaptör Kullanılsın mı? | Neden |
|---|---|---|
| Uyumsuz API'ye sahip üçüncü taraf bir kütüphaneyi kullanma ihtiyacı | Evet | Kütüphaneyi değiştiremezsiniz, bu yüzden ona uyum sağlayın |
| Her iki tarafı da kontrol ediyorsunuz ve değişiklik küçük | Hayır | Ek yönlendirmeden kaçınmak için doğrudan refaktör edin |
| Karmaşık bir sisteme basitleştirilmiş yüksek seviyeli bir arayüz gerekiyor | Hayır | Facade daha uygun bir seçenektir |
| Eski sistemleri kademeli olarak taşıma | Evet | Eski bileşenleri yeni arayüzlere sarmalısınız |
| Yapısı farklı birden çok veri kaynağı | Evet | Adaptörler bunları tek bir şekle birleştirir |
Test ve Performans
Adaptörler, temel mantığı dış sistemlerden ayırarak test edilebilirliği artırır. Bileşenleri izole test etmek için adaptörün arayüzünü mock'layabilir ve çeviri mantığını doğrulamak için adaptörleri ayrı test edebilirsiniz.
Adaptörün performans maliyeti genellikle minimaldir — tipik olarak bir ekstra fonksiyon çağrısı — ve ağ I/O veya veritabanı sorgularıyla karşılaştırıldığında ihmal edilebilir. Çoğu web uygulaması için bakım ve gevşek bağlılık faydaları bu küçük maliyeti fazlasıyla telafi eder. JavaScript, Stack Overflow Developer Survey'de en çok kullanılan dil olmaya devam ederek geliştiricilerin adaptörlerin çözdüğü entegrasyon işleriyle ne sıklıkla karşılaştığını gösteriyor4.
Sıkça sorulan sorular
S: Adapter deseni ne problemi çözer?
A: İstemciden gelen çağrıları adaptee'nin anlayacağı çağrılara çevirerek arayüz uyumsuzluklarını çözer; böylece kodu değiştirmeden yeniden kullanabilirsiniz.
S: Adaptör eski kodla nasıl yardımcı olur?
A: Adaptörler eski modülleri sarar ve modern bir arayüz açığa çıkarır; böylece eski, kararlı kodu riskli yeniden yazımlara başvurmadan yeni uygulamalara entegre edebilirsiniz.
S: Diğer desenlere kıyasla ne zaman Adaptör seçmeliyim?
A: İki uyuşmayan arayüz arasında uyumluluk gerektiğinde Adaptör'ü seçin. Eğer amaç tüm bir alt sistemi basitleştirmekse, bunun yerine Facade kullanın.
İleri Okuma ve Dahili Bağlantılar
- Polimorfizm vs kalıtım derinlemesine: /blog/polymorphism-vs-inheritance
- Eski sistemleri modernize etme stratejileri: /blog/modernizing-legacy-systems
- Adapter deseni referansı ve örnekler: GeeksforGeeks2
Clean Code Guy'ta, kırılgan ve karmaşık kod tabanlarını dayanıklı, test edilebilir ve üzerinde çalışması keyifli varlıklara dönüştüren pratik tasarım kalıplarını uygulamalarında ekiplerine yardımcı oluyoruz. Bir eski sistemle veya zor entegrasyonlarla uğraşıyorsanız, Clean Code Denetimlerimiz size daha sağlıklı bir mimariye yönelik net, uygulanabilir bir yol haritası sunabilir. Daha hızlı ve daha iyi kod göndermenize nasıl yardımcı olabileceğimizi öğrenin.
AI kod yazar.Siz onu uzun süre dayanır hale getirirsiniz.
AI hızlanması çağında, temiz kod sadece iyi bir uygulama değil — ölçeklenen sistemlerle kendi ağırlığı altında çöken kod tabanları arasındaki farktır.