โ Kembali ke Design Pattern
๐ญ
Creational
Factory Method
Mendefinisikan interface untuk membuat objek, tetapi membiarkan subclass atau factory function menentukan class mana yang dibuat.
Masalahnya
Kode client butuh objek, tetapi tidak seharusnya terikat ke class konkretnya. Menulis `new ConcreteType()` di mana-mana membuat penggantian implementasi jadi merepotkan.
Cara Kerja
- โบMemisahkan kode client dari implementasi class konkret
- โบOpen/Closed: tipe produk baru bisa ditambahkan tanpa mengubah kode yang sudah ada
- โบFactory menyimpan semua pengetahuan tentang class mana yang harus dibuat
- โบBisa mengembalikan subclass berbeda berdasarkan parameter input
- โบAbstract Factory memperluas ide ini dengan membuat keluarga objek yang saling terkait
Kapan Digunakan
โSaat kamu belum tahu sebelumnya class mana yang akan dibuat
โSaat logika pembuatan objek perlu dipusatkan dan dikontrol
โSaat subclass yang seharusnya menentukan objek apa yang dibuat
โSaat membuat objek dengan tipe berbeda berdasarkan konfigurasi runtime atau environment
Contoh di Dunia Nyata
๐
iOS
UITableView.dequeueReusableCell(withIdentifier:), UICollectionView cell registration
๐ค
Android
ViewModelProvider.Factory, RecyclerView.ViewHolder creation in onCreateViewHolder
๐
Web
React.createElement, document.createElement, Knex query builder
Contoh Kode
Swift
protocol Notification {
func send(to recipient: String)
}
struct EmailNotification: Notification {
func send(to recipient: String) { print("Email โ \(recipient)") }
}
struct PushNotification: Notification {
func send(to recipient: String) { print("Push โ \(recipient)") }
}
struct SMSNotification: Notification {
func send(to recipient: String) { print("SMS โ \(recipient)") }
}
// Factory function
enum Channel { case email, push, sms }
func makeNotification(for channel: Channel) -> Notification {
switch channel {
case .email: return EmailNotification()
case .push: return PushNotification()
case .sms: return SMSNotification()
}
}
let n = makeNotification(for: .push)
n.send(to: "agus@example.com") // "Push โ agus@example.com"