Apa itu SOLID Principle ?

SOLID merupakan lima prinsip utama yang digunakan oleh OOP ( Object Oriented Programming ). SOLID diperkenalkan oleh Robert C. Martin dan sangat penting dalam arsitektur perangkat lunak modern.
SOLID merupakan akronim dari lima prinsip tersebut, yaitu :
- S — Single Responsibility Principle (SRP), yaitu setiap class / module seharusnya hanya boleh punya 1 tanggung jawab / kewajiban utama. Contohnya dalam class User hanya bertanggung jawab atas entity User aja misal data user, ubah data user, status user. Tidak boleh ada di dalamnya proser transaksi.
- O — Open/Closed Principle (OCP), Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification. Fungsinya untuk menghindari perubahan di entities - entities yang sudah stabil berjalan. Apabila perlu modifikasi, sebaiknya membuat fungsi di luar yang nantinya bisa di panggil ke entity tersebut. Contohnya : Kita punya class
Transaction
yang sudah berjalan baik untuk insert data transaksi. Ada tambahan requirement untuk insert event ke 3rd party (misalnya buat notifikasi, logging, atau analytics). Instead of kamu ubah langsung classTransaction
(yang bisa berisiko merusak fungsi existing), kamu buat service baru misalEventService
yang bertanggung jawab menghandle event tersebut yang nantinya di panggil lewat dependency injection atau observer pattern. - L — Liskov Substitution Principle (LSP), yaitu subclass harus memenuhi kontrak yang didefinisikan oleh super class-nya. Subclass harus bisa menggantikan super class-nya tanpa merusak program. Artinya, struktur subclass harus sesuai dengan yang ada pada super class-nya. Contoh, kita punya
MenuInterface
berisi nama(), harga(), type(). Kita bisa isi dengan Nasi goreng, 50.000, makanan. Harga diharapkan selalu berupa nominal uang positif. Namun kita tidak bisa isi dengan Diskon Nasigoreng, 10%, promo. Karena ada ketidak sesuaian antara harga yang seharusnya integer, di beri value % atau mungkin pengisian nilai negatif. LSP melindungi kita dari class yang secara teknis "compatible" tapi secara logika "incompatible". - I — Interface Segregation Principle (ISP), yaitu lebih baik punya banyak interface kecil dibanding satu interface besar ( segregation = pemisahan ). Pemisahan interface menjadi lebih kecil bertujuan untuk memiliki fokus lebih jelas, hanya tergantung pada metode yang benar-benar mereka butuhkan Daripada satu interface
UserService
denganEditAddress()
,EditUser()
,kyc()
, pecah jadiUserAddressService
,UserStatusService
,UserKYCService
.
Contohnya dalam transaksi, dibutuhkan penggunaan userAddress sehingga cukup menggunakanUserAddressService
. Apabila tidak dipisahkan, menggunakanUserService
, maka fungsi lain seperti KYC yang tidak dibutuhkan di transaksi akan ikut terpanggil walau tidak relevant. - D — Dependency Inversion Principle (DIP), Modul tingkat tinggi tidak boleh bergantung pada modul tingkat rendah. Keduanya harus bergantung pada abstraksi. Gunakan abstraksi (interface/contract) agar modul tingkat atas tidak langsung bergantung pada implementasi detil modul bawah.
Contohnya classTransactionService
dalam melakukan experiment mengakses keExperimentInterface
lebih dulu dari pada secara langsung keAmplitudeService
sehingga apabila suatu saat amplitude di ganti menggunakan braze / platform lain, bisa dengan mudah diubah karena dependency-nya bukan ke amplitude.
SOLID ini bertujuan untuk membuat kode lebih Maintainable (mudah dirawat), Extensible (mudah dikembangkan), Reusable (mudah digunakan ulang), Testable (mudah diuji)
Dalam penggunaan konsep SOLID, polymorphism juga berkaitan erat terutama untuk O L D. Polymorphism secara harfiah berarti "banyak bentuk". Dalam konteks OOP (Object-Oriented Programming), polymorphism memungkinkan satu interface digunakan oleh banyak objek dengan perilaku berbeda, tanpa perlu tahu objek aslinya.
Intinya: kamu bisa memanggil method yang sama pada objek-objek berbeda, dan masing-masing bisa berperilaku sesuai kelasnya sendiri.
Analogi Singkat, kamu punya tombol play()
di YouTube, Spotify, dan TikTok. Sama-sama play()
tapi hasilnya bisa beda: play video, play musik, atau play short.
Contoh implementasi :
sinterface NotifikasiInterface {
public function send($pesan);
}
class EmailService implements NotifikasiInterface {
public function send($pesan) { /* Kirim email */ }
}
class SMSService implements NotifikasiInterface {
public function send($pesan) { /* Kirim SMS */ }
}
dari pada membuat EmailServiceInterface, SMSServiceInterface
, PushNotifServiceInterface
masing-masing, padahal mereka memiliki behaviour yang sama. Lebih baik cukup membuat satu interface NotifikasiInterface
yang bisa di implement di Email
, SMS
, dan PushNotif
.