Apa itu Design Pattern? — Design Patterns

Pernah lagi ngerjain feature baru, terus tiba-tiba mikir "kayaknya pernah solve masalah kayak gini di project lain"? Atau lihat code di codebase lama yang…

Design pattern adalah cara menyelesaikan masalah desain kode yang sering muncul, yang sudah diberi nama dan sudah teruji di banyak project. Bayangin pola jahit di tukang jahit. Pola kerah kemeja dari kertas itu dipakai lagi untuk tiap pelanggan, cuma disesuaikan ukuran dan kainnya. Polanya bukan kemejanya. Design pattern juga begitu: dia bentuk solusinya, sedangkan kode yang kamu tulis adalah kemejanya, beda di tiap project.

🧪 Tebakan cepat: di kode Kurir Kancil versi pertama, layanan baru sameday ditambahkan ke fungsi price saja, lupa ke fungsi eta. Paket sameday 2 kg dicetak dengan console.log("sameday:", price("sameday", 2), "rupiah,", eta("sameday")). Apa yang tercetak? Tebak dulu, jawabannya ada di bagian "Tiga kelompok pattern".

Contoh sepanjang track: Kurir Kancil

Sepanjang track ini kita merawat satu aplikasi: Kurir Kancil, jasa kirim paket kecil. Aplikasinya memberi nomor resi (KCL-0001, KCL-0002, ...), menghitung ongkir per layanan (reguler Rp 10.000 per kg sampai dalam 3 hari, kilat Rp 18.000 per kg sampai dalam 1 hari), dan mengabari pelanggan tiap status paket berubah: dijemput, transit, diantar, terkirim.

Versi pertamanya ditulis cepat, semua dalam satu file:

var lastResi = 0 // bisa dibaca dan diubah file mana pun

function nextResi() {
  lastResi = lastResi + 1
  return "KCL-" + String(lastResi).padStart(4, "0")
}

function price(service, kg) {
  if (service === "reguler") return kg * 10000
  if (service === "kilat") return kg * 18000
}

function eta(service) {
  if (service === "reguler") return "3 hari"
  if (service === "kilat") return "1 hari"
}

function updateStatus(parcel, status) {
  parcel.status = status
  sendSms(parcel)        // tiap pihak baru yang perlu dikabari...
  refreshTracking(parcel) // ...berarti satu baris baru di sini
}

Kodenya jalan. Masalahnya baru terasa waktu aplikasinya berubah: layanan baru harus ditambahkan di beberapa fungsi sekaligus, lastResi bisa tertimpa file lain, dan updateStatus harus diubah tiap ada pihak baru yang perlu dikabari. Tiap lesson berikutnya mengambil satu rasa sakit seperti ini dan menyembuhkannya dengan satu pattern.

Pattern itu pola, bukan potongan kode

Satu pattern punya empat bagian: nama, masalah yang dia selesaikan, bentuk solusinya, dan harganya (kode jadi punya lebih banyak bagian dan nama). Kodenya sendiri gak pernah persis sama. Contohnya pattern Observer: "kabari semua yang mendaftar saat sesuatu terjadi". Di browser bentuknya button.addEventListener("click", fn), di Node.js bentuknya emitter.on("data", fn). Kodenya beda, polanya sama.

Karena punya nama, pattern juga jadi bahasa tim. Bilang "status paket pakai Observer" lebih cepat daripada menjelaskan daftar fungsi yang dipanggil satu per satu.

Tiga kelompok pattern

Buku Design Patterns (1994) karya empat penulis yang dijuluki Gang of Four mengumpulkan 23 pattern dan membaginya jadi tiga kelompok menurut masalahnya:

Kelompok Masalahnya Contoh pattern Rasa sakit di Kurir Kancil
Creational cara object dibuat Factory, Singleton, Builder layanan baru harus ditambah di price dan eta
Structural cara object disusun dan disambung Adapter, Decorator, Facade data kurir mitra memakai nama field lain
Behavioral cara object saling berkabar dan berbagi kerja Observer, Strategy, Command updateStatus diubah tiap ada pihak baru

Contoh creational dari tebakan tadi:

console.log("sameday:", price("sameday", 2), "rupiah,", eta("sameday"))
// sameday: 50000 rupiah, undefined

price sudah tahu sameday, eta belum, jadi eta("sameday") jatuh ke ujung fungsi tanpa return dan hasilnya undefined. Itu jawaban tebakannya. Gak ada error, cuma data yang bolong. Factory Pattern menyembuhkannya dengan menaruh semua yang perlu diketahui tentang satu layanan di satu tempat:

const SERVICES = {
  reguler: { perKg: 10000, eta: "3 hari" },
  kilat: { perKg: 18000, eta: "1 hari" },
  sameday: { perKg: 25000, eta: "hari ini" }, // layanan baru: satu baris
}

function createShipment(service, kg) {
  const s = SERVICES[service]
  return { service, price: kg * s.perKg, eta: s.eta }
}

const p = createShipment("sameday", 2)
console.log("sameday:", p.price, "rupiah,", p.eta) // sameday: 50000 rupiah, hari ini

Di track ini juga ada Module Pattern, cara paling dasar menyembunyikan data di JavaScript. Dia gak masuk tiga kelompok di atas karena gak ada di buku itu, tapi di JavaScript dia fondasi buat pattern lainnya.

Mulai dari masalahnya

Pattern itu obat, jadi pakai saat sakitnya ada. Kalau Kurir Kancil cuma punya satu layanan dan belum ada rencana menambah, createShipment dan SERVICES cuma menambah satu nama dan satu lompatan saat membaca kode, tanpa menyembuhkan apa-apa. Tulis versi sederhana dulu. Begitu perubahan yang sama mulai terasa berulang (layanan kedua, ketiga), baru ubah ke pattern yang cocok.

Urutannya selalu sama: sebut masalahnya dulu ("layanan baru harus diubah di dua tempat"), baru cari pattern yang menyelesaikan masalah itu.

⚠️ Jebakan yang sering ketemu

TL;DR: Design pattern adalah solusi umum yang bisa dipakai ulang untuk masalah desain yang sering muncul. Dia pola, bukan potongan kode: punya nama, masalah, bentuk solusi, dan harga. Tiga kelompoknya: Creational (cara object dibuat: Factory, Singleton, Builder), Structural (cara object disusun: Adapter, Decorator, Facade), Behavioral (cara object berkabar: Observer, Strategy, Command). Contoh sepanjang track ini adalah Kurir Kancil, jasa kirim paket. Mulai dari masalahnya, bukan dari pattern-nya: kalau gak ada rasa sakit yang hilang, jangan pakai pattern.

Yang akan kamu pelajari