โ Kembali ke Design Pattern
๐
Structural
Adapter
Membungkus interface yang tidak kompatibel agar bisa bekerja dengan kode yang sudah ada tanpa perlu diubah.
Masalahnya
Kamu ingin memakai library pihak ketiga atau class lama, tetapi interface-nya tidak sesuai dengan yang diharapkan kodemu. Kamu tidak bisa (atau tidak mau) mengubah salah satu sisinya.
Cara Kerja
- โบMenjembatani dua interface yang tidak kompatibel tanpa mengubah source code-nya
- โบObject adapter membungkus instance (composition); class adapter memakai inheritance
- โบClient hanya melihat target interface, bukan class yang di-adapt
- โบUmum dipakai saat mengintegrasikan SDK pihak ketiga atau kode lama
- โบBisa meng-adapt beberapa adaptee sekaligus jika perlu (multi-adapter)
Kapan Digunakan
โMemakai library pihak ketiga yang interface-nya berbeda dari yang diharapkan kodemu
โMemakai ulang kode lama yang tidak bisa diubah
โBeberapa class dengan interface yang tidak kompatibel perlu bekerja sama
โMenyediakan interface yang stabil saat implementasi di baliknya berubah
Contoh di Dunia Nyata
๐
iOS
UITableViewDataSource & UICollectionViewDataSource adapting model arrays to views
๐ค
Android
RecyclerView.Adapter adapting List<T> to RecyclerView cells
๐
Web
Axios adapters (browser/node), ORM adapters for different databases
Contoh Kode
Swift
// Legacy payment SDK (cannot modify)
class LegacyPaymentSDK {
func makePayment(amount: Double, cardNumber: String) -> Bool {
print("Legacy: charging $\(amount) to \(cardNumber)")
return true
}
}
// Modern interface our app depends on
protocol PaymentProcessor {
func process(amount: Double, method: String) -> Bool
}
// Adapter: wraps legacy to match our interface
class PaymentAdapter: PaymentProcessor {
private let sdk = LegacyPaymentSDK()
func process(amount: Double, method: String) -> Bool {
sdk.makePayment(amount: amount, cardNumber: method)
}
}
// App code only knows about PaymentProcessor
let processor: PaymentProcessor = PaymentAdapter()
processor.process(amount: 99.99, method: "4111-1111-1111-1111")