Empat pilar OOP (abstraction, encapsulation, inheritance, polymorphism) diekspresikan di TypeScript, Go interface implisit, dan PHP — kenapa pattern modern memilih komposisi daripada inheritance — plus refactor hierarki inheritance ke interface + composition di ketiga bahasa

Setiap design pattern yang akan kalian pelajari dibangun dari bahan baku yang sama: empat pilar OOP. Menguasainya berarti membaca katalog pattern apa pun tanpa takut — termasuk yang tidak ada di series ini.
Episode ini membedah keempat pilar di tiga bahasa lab kita, lalu membahas keputusan paling penting dalam desain modern: komposisi atas inheritance.
Menyembunyikan detail, mengekspos kontrak:
interface PaymentGateway {
charge(amount: number): Promise<{ id: string }>;
}Perhatikan Go: interface didefinisikan di sisi konsumen dan dipenuhi secara implisit — tidak ada keyword implements. Ini keputusan desain bahasa yang membuat idiom Go condong ke interface kecil (akan terasa kuat saat membahas ISP di episode 4).
Encapsulation: state internal hanya bisa dimanipulasi lewat method yang mengatur invarian. Inheritance: reuse via hierarki class Child extends Parent — tersedia di TypeScript dan PHP; Go menggantinya dengan embedding struct.
Inti semua pattern behavioral: kode klien memanggil satu kontrak, implementasi bisa berganti tanpa perubahan. Ketiga contoh PaymentGateway di atas mendemonstrasikannya — klien menulis gateway.charge(...) tanpa peduli gateway itu Stripe, Midtrans, atau mock test.
Inheritance punya tiga masalah struktural:
Komposisi menyusun perilaku dengan cara menyuntikkan objek kecil yang saling independen — kombinasi bebas tanpa hierarki. Hampir seluruh GoF modern yang kita pakai (Strategy, Decorator, Adapter) adalah komposisi.
Konsekuensi langsung: buat interface kecil dan fokus pada kebutuhan konsumen, bukan besar dan "lengkap". Interface 2–3 method mudah dipenuhi; interface 12 method adalah beban bagi setiap implementer. Kita dalami ini sebagai bagian SOLID di episode 4.
Target outline: refactor hierarki inheritance menjadi interface + composition di ketiga bahasa.
Skenario klasik yang melanggar: hierarki notifikasi via inheritance.
class Notifier { send(msg: string): void {} }
class EmailNotifier extends Notifier {}
class SmsNotifier extends Notifier {}
// kebutuhan baru: email+sms sekaligus? retry? -> ledakan subclassBandingkan hasilnya: kebutuhan kombinasi baru kini adalah menyusun argumen constructor, bukan membuat class baru. Inilah mesin di balik hampir semua pattern yang akan datang.
Rangkuman episode ini:
Episode 3 mulai seri SOLID: SRP (kenapa god-class adalah musuh utama) dan OCP (ekstensi tanpa modifikasi) — lengkap dengan refactor nyata di NestJS, Fiber, dan Laravel. Sampai jumpa!