Prinsip SOLID

"Pengantar Menuju Design Pattern & Clean Code"

Object-Oriented Programming (OOP) PHP

Pertemuan 13

Tujuan Pembelajaran

  • Mahasiswa memahami ciri-ciri Bad Code (Kode yang rapuh, kaku, dan sulit dipelihara).
  • Mahasiswa memahami 5 pilar pedoman emas OOP yang dirumuskan oleh Robert C. Martin (Uncle Bob), yaitu SOLID.
  • Mahasiswa mampu mengidentifikasi pelanggaran prinsip SOLID pada kode yang ada.
  • Mahasiswa mengetahui cara melakukan Refactoring (memperbaiki struktur kode) agar memenuhi standar industri.

Masalah: Mengapa Kita Butuh SOLID?

Pernahkah Anda membuat aplikasi yang awalnya berjalan lancar, namun saat klien meminta "tambah 1 fitur kecil", tiba-tiba fitur lain ikut error atau buggy?

Ciri-ciri Kode yang Buruk (Bad Design):
  • Rigidity (Kaku): Sangat sulit diubah karena satu perubahan memaksa perubahan di puluhan file lain.
  • Fragility (Rapuh): Jika diubah di satu bagian, aplikasi meledak (error) di bagian lain yang tampaknya tidak berhubungan.
  • Immobility (Tidak Bisa Dipindah): Komponen terlalu bergantung satu sama lain sehingga tidak bisa di-reuse (digunakan ulang) untuk proyek lain.

Untuk mengatasi ini, kita menggunakan 5 pedoman desain OOP yang disebut SOLID.

S - Single Responsibility Principle

"Sebuah Class hanya boleh memiliki satu dan HANYA SATU alasan untuk berubah."

Intinya: Satu Class, Satu Tugas Spesifik. Jangan membuat Class dewa (God Class) yang bisa melakukan segalanya.

// ❌ BURUK: Class User melakukan terlalu banyak hal class User { public function simpanKeDatabase() { ... } public function kirimEmailWelcome() { ... } public function cetakLaporanPDF() { ... } }
// ✅ BAIK: Dipecah sesuai tanggung jawabnya class UserRepository { /* urusan database */ } class UserMailer { /* urusan kirim email */ } class UserReport { /* urusan cetak PDF */ }

O - Open/Closed Principle

"Entitas perangkat lunak harus TERBUKA untuk diperluas (ditambah fitur baru), namun TERTUTUP untuk dimodifikasi (mengubah kode lama)."

Gunakan konsep Interface atau Abstract Class agar saat ada tipe baru, kita tidak perlu membongkar IF-ELSE di dalam class utama.

// ❌ BURUK: Kalau mau tambah metode GoPay, harus bongkar class ini! class Pembayaran { public function proses($tipe) { if ($tipe == "Transfer") { ... } elseif ($tipe == "KartuKredit") { ... } } }
// ✅ BAIK: Cukup buat class baru yang implement Interface, // Class utama tidak perlu dimodifikasi sama sekali! interface MetodeBayar { public function bayar(); } class Transfer implements MetodeBayar { ... } class KartuKredit implements MetodeBayar { ... } class GoPay implements MetodeBayar { ... } // Fitur baru ditambahkan dengan aman

L - Liskov Substitution & I - Interface Segregation

L - Liskov Substitution Principle (LSP)
"Class anak (Child) harus bisa menggantikan peran Class induknya (Parent) tanpa merusak program."
Contoh Pelanggaran: Induk Burung punya fungsi terbang(). Lalu kita membuat class anak Penguin extends Burung. Penguin tidak bisa terbang! Ini akan memicu error. Solusinya, pisahkan menjadi BurungTerbang dan BurungBerenang.
I - Interface Segregation Principle (ISP)
"Jangan memaksa class untuk mengimplementasikan Interface/metode yang tidak mereka butuhkan."
Contoh Pelanggaran: Interface Pekerja punya metode bekerja() dan makan(). Jika kita membuat class Robot implements Pekerja, robot dipaksa punya fungsi makan() yang kosong/error. Solusinya, pecah menjadi interface BisaBekerja dan BisaMakan.

D - Dependency Inversion Principle

"Modul tingkat tinggi (High-level) tidak boleh bergantung langsung pada modul tingkat rendah (Low-level). Keduanya harus bergantung pada abstraksi (Interface/Abstract Class)."

// ❌ BURUK: Aplikasi (High-level) sangat bergantung pada MySQL (Low-level). // Jika kita ingin pindah ke database MongoDB, seluruh kode aplikasi rusak. class TokoOnline { private $db; public function __construct(MySQLConnection $db) { $this->db = $db; } }
// ✅ BAIK: Bergantung pada Interface. // Kita bisa melempar class koneksi apapun asalkan ia mematuhi Interface tersebut. interface DatabaseInterface { public function connect(); } class TokoOnline { private $db; public function __construct(DatabaseInterface $db) { $this->db = $db; } }

Simulasi OCP (Open/Closed Principle)

Skenario: Bos meminta Anda menambahkan metode pembayaran baru (M-Banking). Mari lihat apa yang terjadi jika sistem Anda dirancang secara buruk (Bad) vs secara baik (SOLID).

Pilih simulasi untuk melihat proses penambahan fitur baru...

Kesimpulan

SOLID bukanlah aturan yang akan membuat aplikasi Anda berjalan lebih cepat, melainkan aturan yang membuat Anda sebagai Programmer bertahan hidup lebih lama tanpa pusing memelihara kode.

Setelah menguasai SOLID, Anda sudah siap mempelajari Design Pattern (Pola Desain Teruji) seperti Factory Pattern, Singleton, Observer, dan banyak lagi yang digunakan di Framework modern (seperti Laravel, CodeIgniter, dll).