Jelajahi pola desain Adapter dengan contoh TypeScript dunia nyata. Pelajari cara menjembatani API yang tidak kompatibel, merefaktor kode warisan, dan membangun sistem yang dapat diskalakan.
January 7, 2026 (3mo ago)
Panduan Anda untuk Pola Desain Adapter dalam Clean Code
Jelajahi pola desain Adapter dengan contoh TypeScript dunia nyata. Pelajari cara menjembatani API yang tidak kompatibel, merefaktor kode warisan, dan membangun sistem yang dapat diskalakan.
← Back to blog
The Adapter design pattern pada dasarnya adalah perantara. Anggap saja sebagai penerjemah yang memungkinkan dua sistem yang tidak kompatibel untuk saling berbicara tanpa hambatan. Intinya adalah membuat kelas yang sudah ada bekerjasama tanpa pernah menyentuh kode sumber aslinya. Ini adalah padanan perangkat lunak dari adaptor perjalanan yang memungkinkan Anda mencolokkan elektronik Kanada ke stopkontak Eropa.
Pola ini adalah batu penjuru dari kode yang bersih dan mudah dipelihara, terutama ketika Anda mencoba mengintegrasikan perpustakaan pihak ketiga atau mengatur sistem warisan.1
Mengapa Basis Kode Anda Membutuhkan Pola Adapter

Bayangkan ini: Anda sedang berada di Eropa, mencoba mencolokkan laptop Kanada ke dinding. Itu tidak muat. Charger Anda berfungsi baik, stopkontak berfungsi baik, tetapi antarmuka mereka benar-benar berbeda. Masalah yang sama persis terjadi sepanjang waktu dalam pengembangan perangkat lunak ketika kita perlu dua sistem, yang tidak dirancang untuk saling bertemu, tiba-tiba bekerja bersama.
Di situlah pola Adapter berperan. Ini adalah adaptor perjalanan universal Anda untuk kode, menciptakan jembatan tanpa celah antara komponen yang tidak cocok.
Menjembatani Kesenjangan dalam Pengembangan Modern
Saat ini kita jarang membangun semuanya dari awal. Kita merakit solusi dari perpustakaan pihak ketiga, API eksternal, dan sistem warisan. Ini mempercepat pengiriman tetapi menciptakan antarmuka yang tidak kompatibel dan godaan jalan pintas yang menimbulkan masalah jangka panjang:
- Duplikasi kode: logika translasi yang sama berakhir tersebar di seluruh aplikasi.
- Kopling tinggi: logika bisnis menjadi kacau dengan detail layanan eksternal.
- Utang teknis meningkat: setiap perubahan API memicu perburuan kode integrasi yang rapuh.
Pola Adapter memberi Anda kelas adapter khusus yang menangani translasi di satu tempat, melindungi logika aplikasi inti Anda dan membuat integrasi lebih mudah dipelihara. Pendekatan ini umum di tim yang memprioritaskan arsitektur modular dan modernisasi bertahap.2
Pola Adapter bukan sekadar trik untuk membuat sesuatu bekerja. Ia melindungi kesederhanaan dan integritas logika aplikasi inti Anda dengan menjaganya dari detail kotor sistem eksternal.
Adapter Mendorong Kode yang Bersih dan Dapat Diskalakan
Sebuah adapter adalah strategi untuk membangun arsitektur yang fleksibel yang dapat berubah tanpa penulisan ulang total. Anda bisa menukar layanan atau memensiunkan sistem warisan dengan menambahkan atau mengganti adapter daripada menyentuh kode klien. Stabilitas itu mempercepat pengembangan fitur dan mengurangi risiko integrasi.2
Bagaimana Pola Adapter Sebenarnya Bekerja
Pada intinya, pola ini menciptakan pemisahan yang bersih antara bagian-bagian sistem Anda sehingga mereka dapat berkembang secara independen. Empat pemain membuat pola ini mudah dipahami:
- The Client: kode yang membutuhkan sesuatu dilakukan dan mengharapkan antarmuka yang sederhana dan stabil.
- The Target: antarmuka bersih yang digunakan Client.
- The Adaptee: komponen yang ada dengan antarmuka yang tidak kompatibel (seringkali tidak dapat diubah).
- The Adapter: mengimplementasikan Target dan menerjemahkan pemanggilan ke Adaptee.

Client hanya pernah berbicara dengan antarmuka Target; Adapter dengan tenang menerjemahkan untuk Adaptee. Desain ini sejalan dengan Prinsip Open/Closed: Anda dapat mengintegrasikan layanan baru dengan menulis adapter baru sambil membiarkan kode klien yang ada tidak tersentuh.1
Tujuan utama pola Adapter adalah mengubah antarmuka sebuah kelas menjadi antarmuka lain yang diharapkan klien. Adapter memungkinkan kelas bekerja bersama yang seharusnya tidak bisa karena antarmuka yang tidak kompatibel.3
Membangun Adapter di TypeScript dengan Contoh Nyata

Di bawah ini adalah dua contoh TypeScript praktis yang mencerminkan masalah dunia nyata yang umum: mengadaptasi API XML warisan dan menstandarisasi gateway pembayaran pihak ketiga.
Contoh 1: Mengadaptasi API XML Warisan ke JSON
Skenario: frontend React modern Anda mengharapkan JSON, tetapi satu-satunya sumber data adalah layanan warisan yang mengembalikan XML. Klien harus menggunakan antarmuka IUserService yang bersih; LegacyUserService berbicara XML. Adapter menjembatani keduanya.
The Incompatible Adaptee
// Adaptee: The old service with an incompatible interface
class LegacyUserService {
fetchUsersXML(): string {
return `
<users>
<user id="1">
<name>Alice</name>
<email>alice@example.com</email>
</user>
<user id="2">
<name>Bob</name>
<email>bob@example.com</email>
</user>
</users>
`;
}
}
The Target Interface and Adapter
interface IUser {
id: number;
name: string;
email: string;
}
interface IUserService {
getUsers(): Promise<IUser[]>;
}
class UserServiceAdapter implements IUserService {
private adaptee: LegacyUserService;
constructor(legacyService: LegacyUserService) {
this.adaptee = legacyService;
}
async getUsers(): Promise<IUser[]> {
const xmlData = this.adaptee.fetchUsersXML();
// Use a robust XML parser in production (e.g., xml2js).
console.log("Translating XML to JSON...");
return [
{ id: 1, name: "Alice", email: "alice@example.com" },
{ id: 2, name: "Bob", email: "bob@example.com" },
];
}
}
Dengan adapter ini, kode klien berbicara ke IUserService dan tetap awam terhadap XML.
Contoh 2: Menstandarisasi Gateway Pembayaran Pihak Ketiga
Skenario: aplikasi Anda menggunakan antarmuka standar IPaymentProcessor, tetapi gateway PayWizard memiliki metode seperti startTransaction dan verifyPaymentStatus. Adapter memetakan panggilan standar Anda ke API PayWizard.
The Inconsistent Adaptee
class PayWizard {
startTransaction(amount: number, cardDetails: string): string {
console.log(`PayWizard: Initiating transaction for $${amount}.`);
const transactionId = "pw_" + Math.random().toString(36).substr(2, 9);
return transactionId;
}
verifyPaymentStatus(transactionId: string): boolean {
console.log(`PayWizard: Verifying status for ${transactionId}.`);
return true;
}
}
The Target Interface and Adapter
interface IPaymentProcessor {
processPayment(amount: number, cardInfo: string): Promise<string>;
checkStatus(id: string): Promise<boolean>;
}
class PayWizardAdapter implements IPaymentProcessor {
private payWizard: PayWizard;
constructor() {
this.payWizard = new PayWizard();
}
async processPayment(amount: number, cardInfo: string): Promise<string> {
console.log("Adapter: Translating 'processPayment' to 'startTransaction'.");
return this.payWizard.startTransaction(amount, cardInfo);
}
async checkStatus(id: string): Promise<boolean> {
console.log("Adapter: Translating 'checkStatus' to 'verifyPaymentStatus'.");
return this.payWizard.verifyPaymentStatus(id);
}
}
Menggunakan adapter menjaga kode aplikasi Anda tetap bersih dan konsisten di berbagai penyedia.
Merefaktor Kode Warisan dengan Adapter

Setiap proyek pada akhirnya menghadapi kode warisan. Pola Adapter memungkinkan Anda menghindari penulisan ulang besar yang berisiko dengan membungkus sistem lama dengan antarmuka Target modern dan memigrasikan kode klien secara bertahap. Pendekatan ini mengurangi risiko dan mendukung rencana modernisasi yang terkontrol.2
Rencana Migrasi Langkah demi Langkah
- Definisikan antarmuka Target ideal Anda.
- Buat kelas Adapter yang mengimplementasikan antarmuka tersebut dan menerima Adaptee warisan.
- Terapkan logika translasi di dalam adapter.
- Migrasikan kode klien secara bertahap untuk menggunakan Adapter.
Mempercepat Refaktor dengan AI
Alat AI modern dapat mempercepat pembuatan kode boilerplate, membiarkan Anda fokus pada logika pemetaan yang krusial, tetapi keputusan arsitektural tetap menjadi tanggung jawab tim. Gunakan alat untuk membuat kerangka adapter lalu tulis tes yang memvalidasi pemetaannya.
Menggunakan adapter bukan sekadar perbaikan sementara; ini adalah investasi strategis dalam kesehatan arsitektural yang memungkinkan modernisasi bertahap.2
Memilih antara Adapter dan Pola Lain
Memilih pola yang tepat penting. Adapter, Decorator, Proxy, dan Façade bisa tampak mirip tetapi melayani tujuan yang berbeda. Gunakan Adapter untuk mengubah antarmuka; gunakan Decorator untuk menambahkan perilaku; gunakan Proxy untuk mengendalikan akses; gunakan Façade untuk menyederhanakan subsistem yang kompleks.
Adapter vs Decorator
Adapter menerjemahkan sebuah antarmuka. Decorator menambahkan tanggung jawab sambil mempertahankan antarmuka asli.
Adapter vs Proxy
Proxy mempertahankan antarmuka yang sama dan mengendalikan akses atau menambahkan inisialisasi malas, caching, atau logging. Adapter mengubah antarmuka sehingga klien dapat menggunakan komponen yang seharusnya tidak kompatibel.
Adapter vs Façade
Façade menyederhanakan sebuah subsistem di balik satu antarmuka. Adapter fokus pada konversi antarmuka sebuah objek sehingga dua komponen dapat berinteroperasi.
| Pattern | Primary Intent | When to Use |
|---|---|---|
| Adapter | Convert one interface to another | When an existing class must work with an incompatible client. |
| Decorator | Add responsibilities | When you want to extend behavior dynamically. |
| Proxy | Control access | When you need lazy loading, access control, or logging. |
| Façade | Simplify a subsystem | When you want a single entry point to complex behavior. |
Membawa Pola Adapter ke Tim Anda
Untuk menghindari penggunaan berlebihan, tetapkan batasan yang jelas untuk pembuatan adapter:
- Dokumentasi: setiap adapter membutuhkan README yang menyatakan Adaptee, antarmuka Target, dan pemetaan.
- Pengujian: wajibkan unit test yang menegaskan logika translasi.
- Pemantauan kinerja: benchmark adapter kritis ketika mereka berada di jalur panas.
Tambahkan pemeriksaan otomatis untuk menegakkan aturan ini di CI dan jaga konsistensi adapter di seluruh basis kode. Sediakan contoh dan template di situs dokumentasi internal Anda atau tautkan ke panduan seperti modernizing legacy systems.
Punya Pertanyaan? Mari Bicara Adapter
Tanya & Jawab
T: Kapan adapter lebih baik daripada penulisan ulang penuh?
J: Gunakan adapter ketika komponen yang ada berfungsi tetapi antarmukanya tidak cocok dengan kebutuhan Anda—terutama untuk sistem warisan yang stabil atau API pihak ketiga yang tidak Anda kendalikan. Jika komponen tersebut buggy atau kurang fitur yang diperlukan, penulisan ulang mungkin diperlukan.
T: Apakah adapter menambah overhead kinerja yang signifikan?
J: Adapter menambah sedikit overhead—satu panggilan metode ekstra atau langkah konversi—tetapi dalam sebagian besar aplikasi bisnis ini tidak signifikan dibandingkan biaya jaringan atau I/O. Untuk sistem sensitif-latensi, lakukan benchmark pada adapter.
T: Bagaimana tim saya harus menguji adapter?
J: Tulis unit test yang berfokus pada pemetaan antara Target dan Adaptee. Mock Adaptee bila perlu dan sertakan tes integrasi untuk memastikan adapter berperilaku benar dengan dependensi nyata.
AI menulis kode.Anda membuatnya bertahan.
Di era akselerasi AI, kode bersih bukan hanya praktik yang baik — ini adalah perbedaan antara sistem yang berkembang dan codebase yang runtuh di bawah beratnya sendiri.