DEV Community

Cover image for Dari OOP ke SOLID: Semua yang Perlu Kamu Tahu dalam Satu Artikel
Sanudin
Sanudin

Posted on

Dari OOP ke SOLID: Semua yang Perlu Kamu Tahu dalam Satu Artikel

πŸ• ~8 menit baca

πŸ“ Catatan tentang artikel ini
Artikel ini dibuat berdasarkan catatan belajar pribadi saya tentang OOP dan prinsip SOLID. Untuk membuat catatan tersebut lebih mudah dibaca dan bermanfaat β€” bagi saya dan orang lain β€” saya menggunakan bantuan AI untuk mengembangkan dan menyusunnya menjadi artikel blog. Ide, perjalanan belajar, dan pemahamannya adalah milik saya; AI membantu di bagian penulisan dan penyajiannya.


Kode yang enak dibaca dan mudah diubah bukan kebetulan. Di balik setiap codebase yang menyenangkan untuk dikerjakan, ada sekumpulan ide yang memandu bagaimana semuanya disusun dan dihubungkan.

Artikel ini membahas perjalanan lengkap itu β€” mulai dari apa itu OOP, bagaimana objek saling berhubungan, seperti apa desain yang buruk, hingga akhirnya: lima prinsip SOLID yang menyatukan semuanya.

Yuk mulai.


Bagian 1: Apa Itu OOP?

Object Oriented Programming (OOP) adalah cara menulis kode yang mencerminkan dunia nyata. Alih-alih satu daftar panjang instruksi, kamu mengelompokkan data dan perilaku yang saling berkaitan ke dalam objek.

πŸ€– Bayangkan mainan robot. Robot punya properti (warna, tinggi, baterai) dan perilaku (berjalan, berbicara, melambaikan tangan). Dalam OOP, robot itu adalah objek β€” dan cetak biru yang digunakan untuk membuatnya disebut class.

Dua istilah kunci:

  • Class β€” cetak biru (template)
  • Object β€” wujud nyata yang dibuat dari cetak biru tersebut

Empat Pilar OOP

Pilar Fungsinya
Inheritance Class anak mewarisi properti dan perilaku dari class induk
Encapsulation Data internal disembunyikan β€” akses dari luar hanya melalui jalur yang ditentukan
Abstraction Kerumitan internal disembunyikan; hanya yang perlu digunakan saja yang ditampilkan
Polymorphism Aksi yang sama bisa berperilaku berbeda tergantung pada objeknya

Bagian 2: Bagaimana Objek Saling Berhubungan

Objek tidak hidup sendiri-sendiri. Mereka terhubung, bekerja sama, dan saling bergantung β€” dan jenis hubungannya penting.

Asosiasi

Dua objek saling mengenal dan bisa berinteraksi. Ada tiga jenis kardinalitas:

  • One-to-one β€” satu orang satu paspor
  • One-to-many β€” satu guru, banyak murid
  • Many-to-many β€” banyak murid, banyak mata pelajaran

Dalam asosiasi, ketika satu objek "memiliki" objek lain, hubungannya bisa berupa:

  • Aggregation (longgar) β€” objek anak bisa hidup tanpa induknya. Tas ransel berisi buku, tapi bukunya tetap ada meski tasnya dibuang.
  • Composition (erat) β€” objek anak tidak bisa eksis tanpa induknya. Rumah punya kamar; hancurkan rumahnya, kamarnya ikut lenyap.

Dependency

Hubungan sementara berbasis pemakaian. Satu class memakai class lain di dalam sebuah method, tapi tidak menyimpannya secara permanen. Lebih lemah dari asosiasi.

Generalization & Realization

  • Generalization β€” mengangkat sifat-sifat yang sama dari beberapa class ke satu superclass (pewarisan)
  • Realization β€” sebuah class mengimplementasikan interface, berjanji untuk memenuhi kontrak yang sudah didefinisikan

Bagian 3: Seperti Apa Desain yang Buruk?

Sebelum belajar aturannya, penting untuk memahami apa yang sedang kita hindari. Robert C. Martin mengidentifikasi tiga gejala desain yang buruk:

πŸͺ¨ Rigidity (Kekakuan) β€” sistem susah diubah. Sentuh satu hal, dan banyak hal lain ikut perlu diperbarui. Developer jadi takut untuk melakukan perubahan.

πŸͺ Fragility (Kerapuhan) β€” sistem rusak di tempat yang tidak terduga saat kamu melakukan perubahan. Kamu memperbaiki bug di modul pembayaran, tiba-tiba notifikasi email berhenti berfungsi.

πŸ—οΈ Immobility (Ketidakmampuan Dipindahkan) β€” komponen yang berguna tidak bisa dipakai ulang. Mereka terlalu kusut dengan sekitarnya sehingga mencabutnya butuh lebih lama dari menulis ulang dari awal.

Ketiganya punya akar penyebab yang sama: pengelolaan dependensi antar komponen yang buruk.


Bagian 4: SOLID

SOLID adalah lima prinsip yang secara langsung mengatasi masalah di atas. Masing-masing menargetkan kegagalan desain yang spesifik.


S β€” Single Responsibility Principle

"Sebuah modul harus bertanggung jawab pada satu, dan hanya satu, aktor."

Setiap class harus punya tepat satu alasan untuk berubah β€” ia melayani satu aktor (satu kelompok stakeholder).

πŸ‘¨β€πŸ³ Seorang pekerja restoran yang sekaligus menjadi koki, kasir, satpam, dan pengantar makanan adalah bencana yang menunggu terjadi. Perubahan di satu peran mengganggu semua peran lainnya.

Pisahkan class-mu. Satu tanggung jawab per class.


O β€” Open/Closed Principle

"Artefak perangkat lunak harus terbuka untuk ditambahkan, tapi tertutup untuk dimodifikasi."

Tambahkan perilaku baru dengan cara memperluas β€” bukan mengedit kode lama yang sudah berjalan.

πŸ”Œ Stop kontak memungkinkan kamu mencolokkan perangkat baru tanpa perlu membongkar kabelnya. Itulah OCP dalam praktik.

Ketika kebutuhan berubah, tambahkan kode baru di samping yang lama β€” jangan tulis ulang yang sudah berjalan.


L β€” Liskov Substitution Principle

"Jika S adalah subtipe dari T, objek bertipe T bisa digantikan dengan objek bertipe S tanpa mengubah kebenaran program."

Sebuah subclass harus sepenuhnya bisa menggantikan class induknya. Setiap janji yang dibuat induk, harus dipenuhi oleh anak.

πŸ€– Kalau robot induk bisa memasak, robot anak juga harus bisa memasak β€” bukan melempar error atau diam saja tanpa melakukan apa-apa.

Kalau subclass-mu punya method kosong, implementasi stub, atau melempar "not supported" β€” itu pelanggaran Liskov.


I β€” Interface Segregation Principle

"Client tidak boleh dipaksa bergantung pada interface yang tidak mereka gunakan."

Jangan buat interface besar yang memaksa class mengimplementasikan method yang tidak mereka butuhkan. Pecah interface menjadi bagian-bagian kecil yang lebih fokus.

🍴 Jangan berikan setiap pelanggan restoran pisau steak, sendok sup, sumpit, dan tusuk fondue ketika mereka hanya memesan sup.

Interface yang lebih kecil = dependensi yang lebih sempit = perubahan tetap terlokalisir.


D β€” Dependency Inversion Principle

"Modul tingkat tinggi tidak boleh bergantung pada modul tingkat rendah. Keduanya harus bergantung pada abstraksi."

Logika bisnis tidak boleh terkait langsung dengan implementasi spesifik. Ia harus bicara dengan interface β€” dan detail tingkat rendah yang mengimplementasikan interface tersebut.

πŸ€– Jangan solder spatula ke tangan robot. Beri tangannya konektor standar, dan biarkan alat-alatnya bisa diganti-ganti.

Inilah yang membuat infrastruktur (database, API, file system) bisa diganti tanpa menyentuh logika bisnis.


Ringkasan Cepat: SOLID Sekilas

Prinsip Masalah yang diatasi Pertanyaan kuncinya
SRP Class mengerjakan terlalu banyak hal "Apakah class ini melayani lebih dari satu kelompok stakeholder?"
OCP Mengedit kode lama untuk menambah fitur "Bisakah ini ditambahkan sebagai ekstensi, bukan modifikasi?"
LSP Hirarki pewarisan yang rusak "Bisakah anak menggantikan induk tanpa ada yang rusak?"
ISP Interface gemuk dengan method yang tidak dipakai "Apakah class ini dipaksa mengimplementasikan sesuatu yang tidak dibutuhkan?"
DIP Logika bisnis terikat ke infrastruktur "Apakah kode tingkat tinggi bergantung pada class konkret yang seharusnya tidak?"

Mulai dari Mana?

Kalau kamu baru pertama kali menerapkan ini:

  1. Mulai dengan SRP β€” cari class yang "mengerjakan terlalu banyak" dan pecah
  2. Periksa pewarisan untuk pelanggaran LSP β€” method kosong adalah tanda peringatannya
  3. Tambahkan interface di batas infrastruktur β€” itulah DIP dalam praktik

Prinsip-prinsip ini bukan checklist. Mereka adalah pertanyaan yang perlu kamu ajukan setiap kali duduk untuk menulis kode.


Originally published at sanudin.dev

Top comments (0)