Prinsip SOLID - Penjelasan Lengkap Beserta Contohnya - Galih Laras Prakoso

Rabu, 30 Januari 2019

Prinsip SOLID - Penjelasan Lengkap Beserta Contohnya
Prinsip SOLID - Penjelasan Lengkap Beserta Contohnya
Setelah mempelajari tentang pemrograman berorientasi objek, sekarang saatnya kita sama-sama memahami lima buah prinsip yang akan membantu kita membuat design yang lebih baik dalam mengembangkan software.

Lima buah prinsip yang akan kita pelajari disingkat menjadi satu buah kata yaitu S.O.L.I.D. Prinsip ini dipopulerkan oleh Robert C. Martin atau yang biasa dipanggil dengan nama Uncle Bob. Jika kita mengaplikasikan masing-masing prinsip dengan tepat, maka kelima prinsip ini dapat membuat baris kode yang kita tulis semakin extendable dan easier to read.

Sebaliknya jika kita mengembangan software dengan menggunakan design yang buruk, maka baris kode yang kita tulis akan menjadi sangat kaku dan rapuh, sedikit saja kita melakukan perubahan dapat menghasilkan banyak bug. Maka dari itu, sangat penting bagi kita untuk mempelajari dan menerapkan kelima prinsip yang disebut SOLID ini.

prinsip-solid-pada-pemrograman

Oke, sebelumnya kita semua harus percaya bahwa :
Disiplin itu memang terkesan mengekang, tetapi sebenarnya dia membebaskan.
Menerapkan prinsip SOLID tentunya memerlukan disiplin yang kuat, kita yang mungkin sering berpikir bahwa disiplin itu mengekang, harus mulai merubah pola pikir kita. Karena ketika kita disiplin saat ini, itu akan membebaskan banyak masalah di masa yang akan datang.

Langsung saja aku akan mencoba untuk menjelaskan kelima prinsip SOLID dengan sesederhana mungkin sehingga mudah dimengerti.

#1 Single Responsibility Principle
Sebuah class harus memiliki satu, dan hanya satu alasan untuk berubah.
Satu class hanya boleh mengerjakan satu tujuan. Anti multitasking-multitasking club. Hindari menciptakan GOD Class yang mampu mengerjakan banyak hal. Semua methods dan properties harus bekerja untuk mengerjakan tujuan yang sama.

Ketika sebuah class sudah mulai mengerjakan beberapa tujuan, maka class tersebut harus dipecah menjadi class baru. Atau ketika sebuah class memiliki lebih dari satu alasan untuk berubah, maka class tersebut harus dipecah menjadi class baru.
Contoh :
package galihlprakoso.com.solidprinciple;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Locale;
/**
*
* @author galihlarasprakoso
*/
class GODClass {
private ArrayList<Integer> getListDataHarga(){
ArrayList<Integer> listDataHarga = new ArrayList<>();
listDataHarga.add(5000);
listDataHarga.add(6000);
listDataHarga.add(7000);
listDataHarga.add(8000);
listDataHarga.add(9000);
listDataHarga.add(10000);
return listDataHarga;
}
public ArrayList<String> ambilListHarga(){
ArrayList<Integer> listDataHarga = getListDataHarga();
ArrayList<String> listDataHargaFormatted = new ArrayList<>();
for (int i = 0; i < listDataHarga.size(); i++) {
String hargaFormatted = formatMataUang(listDataHarga.get(i));
listDataHargaFormatted.add(hargaFormatted);
}
return listDataHargaFormatted;
}
public String formatMataUang(Integer angka){
Locale localeID = new Locale("in", "ID");
NumberFormat format = NumberFormat.getCurrencyInstance(localeID);
return format.format(angka);
}
}
Pada contoh di atas, kita dapat melihat bahwa class yang bernama GODClass benar-benar bertingkah seperti dewa. Mampu melakukan banyak hal, kelihatannya bagus, berarti dia multitalent :v wkwkwk. Gak -_- , itu melanggar prinsip yang pertama.

Misalnya suatu saat kita ingin merubah listDataHarga, cara menyajikan data dan format harga. Maka GODClass akan memiliki 3 alasan untuk berubah dan itu melanggar prinsip SOLID yang pertama karena sebuah class harus memiliki satu, dan hanya satu alasan untuk berubah.

#2 Open/Closed Principle
“Classes should be open for extension but closed for modification”
Sengaja ga saya translate karena saya susah bahasa indonesiain :D jadi aneh. Maksud dari prinsip kedua ini adalah misalnya ada sebuah tim programmer yang sedang mengerjakan sebuah aplikasi, suatu hari ada sebuah class yang ditulis oleh programmer yang bernama Paijo, nah setelah Paijo selesai menulis class-nya ada programmer lain yang bernama Suparman yang ingin menggunakan class yang dibuat oleh Paijo namun dia menginginkan ada beberapa perubahan pada class tersebut. Nah, seharusnya Suparman dapat dengan mudah meng-extend class yang dibuat oleh Paijo. Tetapi dengan catatan bahwa Suparman tidak perlu merubah class yang ditulis oleh paijo.
Contoh :
package galihlprakoso.com.solidprinciple;
/**
*
* @author galihlarasprakoso
*/
//Contoh yang tidak menggunakan
//Open/Closed Principle
class WarungMakanBuLastri{
public void sajikanMakananBerdasarkanPesanan(String pesanan){
if(pesanan.equalsIgnoreCase("Nasi Goreng")){
System.out.println("Menyajikan Nasi Goreng");
}else if(pesanan.equalsIgnoreCase("Mie Goreng")){
System.out.println("Menyajikan Mie Goreng");
}
//Jika kita ingin menambahkan menu pesanan baru,
//Kita harus menambahkan kondisi (if) lagi disini
//dengan merubah class Warung Makan
//Tentunya ini melanggar prinsip Open/Closed Principle
}
}
//Contoh yang menggunakan
//Open/Closed Principle
class WarungMakanBuSri{
public void sajikanMakananBerdasarkanPesanan(Pesanan pesanan){
pesanan.sajikanPesanan();
}
}
interface Pesanan{
void sajikanPesanan();
}
class NasiGoreng implements Pesanan{
@Override
public void sajikanPesanan() {
System.out.println("Menyajikan Nasi Goreng");
}
}
class MieGoreng implements Pesanan{
@Override
public void sajikanPesanan() {
System.out.println("Menyajikan Mie Goreng");
}
}
//Untuk menambah menu, kita tidak perlu mengubah kode yang ada
//di class WarungMakanBuSri
//Misalnya kita ingin menambah menu makanan SateAyam
//Kita cukup membuat class baru bernama SateAyam
class SateAyam implements Pesanan{
@Override
public void sajikanPesanan() {
System.out.println("Menyajikan Sate Ayam");
}
}
#3 Liskov Substitution Principle
“Parent classes should be easily substituted with their child classes without blowing up the application”.
 Class induk harus dapat dengan mudah digantikan dengan class turunannya tanpa menghancurkan keseluruhan aplikasi. Langsung saja kita ambil sebagai contoh misalnya :

package galihlprakoso.com.solidprinciple;
/**
*
* @author galihlarasprakoso
*/
class AlatMusik {
public void berbunyi(){
System.out.println("Bunyi alat musik...");
}
}
class Gitar extends AlatMusik{
@Override
public void berbunyi(){
System.out.println("Jrengg...");
}
}
class Biola extends AlatMusik{
@Override
public void berbunyi(){
System.out.println("Ngek ngok ngek ngik...");
}
}
Pada kode di atas kita bisa langsung melihat bahwa ada class induk yang bernama AlatMusik , class induk tersebut memiliki dua class turunan yang bernama Gitar dan Biola. Masing - masing dapat mengimplementasikan method berbunyi() nya sendiri-sendiri tanpa merusak atau mengotak atik class induknya sehingga hal tersebut tidak akan merusak jalannya aplikasi.

#4 Interface Segregation Principle
“A client should not be forced to use an interface, if it doesn’t need it.”
Jika kalian sudah mulai belajar PBO, pastinya kamu tidak asing dengan yang namanya interface. Yak, maksud dari prinsip yang ke empat ini sangatlah sederhana yaitu banyak interface yang memiliki tujuan spesifik lebih baik daripada hanya satu interface namun memiliki banyak tujuan. Langsung aja lihat contoh di bawah ini :
package galihlprakoso.com.solidprinciple;
/**
*
* @author galihlarasprakoso
*/
//Implementasi yang tidak memenuhi prinsip
interface InteraksiPenggunaDenganLayar {
void menekan();
void menggeser();
}
//Implementasi yang memenuhi prinsip
interface InteraksiMenekan{
void menekan();
}
interface InteraksiMenggeser{
void menggeser();
}
Dengan melihat contoh diatas tentunya kita bisa langsung paham bahwa contoh yang salah di atas adalah contoh yang memaksa penggunanya untuk mengimplementasikan semua method, sementara yang benar tidak.

Misalnya suatu saat pengguna hanya ingin mengimplementasikan fungsi untuk menangani ketika ada interaksi sentuhan. Masa iya dia harus mengimplementasikan fungsi lain yang tidak dia butuhkan? kan tidak efisien.

#5 Dependency Inversion
“High level modules should not depend on low-level modules, but should depend on abstraction.”
Yak, sampailah kita pada prinsip yang terakhir. Pengertian dari prinsip ini adalah bahwa class yang dikategorikan sebagai high-level class tidak boleh bergantung pada low-level class tetapi harus bergantung pada abstraksi.

Waduh, gimana sih maksudnya? maksudnya adalah setiap class tidak boleh berinteraksi secara langsung. Kenapa? karena itu akan menyebabkan terjadinya tight coupling atau keterikatan yang kuat antara kedua class tersebut. Lalu bagaimana class berkomunikasi? Menggunakan Interface. 

Dengan begitu, high-level class tidak perlu khawatir aplikasi akan rusak jika terjadi perubahan pada low-level class. Langsung saja deh lihat contohnya :
package galihlprakoso.com.solidprinciple;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author galihlarasprakoso
*/
interface PekerjaBangunan {
void kerja();
}
class TukangBatu implements PekerjaBangunan{
@Override
public void kerja() {
buatPondasi();
memasangBatuBata();
mengecor();
}
private void buatPondasi(){
System.out.println("Membuat pondasi...");
}
private void memasangBatuBata(){
System.out.println("Memasang batu bata...");
}
private void mengecor(){
System.out.println("Mengecor...");
}
}
class TukangCat implements PekerjaBangunan{
@Override
public void kerja() {
mengecat();
}
private void mengecat(){
System.out.println("Mengecat...");
}
}
class ProyekBangunan{
List<PekerjaBangunan> pekerja;
public ProyekBangunan(List<PekerjaBangunan> pekerja) {
this.pekerja = pekerja;
}
public void mulaiProyek(){
for (int i = 0; i < pekerja.size(); i++) {
pekerja.get(i).kerja();
}
}
}

Perhatikan class ProyekBangunan yang ada pada contoh di atas. Kita bisa melihat bahwa method mulaiProyek() yang ada pada ProyekBangunan memanggil method kerja() pada setiap class yang mengimplementasikan interface PekerjaBangunan tanpa mengkhawatirkan bagaimana masing-masing pekerja melakukan pekerjaannya yang dia tahu hanya PekerjaBangunan pasti bisa kerja. Dengan begini class ProyekBangunan tidak terikat secara langsung dengan setiap class pekerja dan jika pekerja suatu saat bekerja dengan cara yang berbeda, high-level class seperti ProyekBangunan tidak perlu khawatir dengan perubahan tersebut.

Yak, kira-kira begitulah penjelasan yang bisa kusampaikan kepada teman-teman semua. Jika mungkin aku salah dalam menjelaskan tolong dikoreksi dan jika kalian ada pertanyaan jangan sungkan - sungkan untuk memulai diskusi dengan berkomentar pada kolom komentar yang berada di bawah. Semoga bermanfaat!
Galih Laras Prakoso

Web App Developer, Mobile App Developer and Startup Enterpreneur.

1 komentar:

  1. dalam dependency principle modul yg bertanggung jawab dengan fungsi yg sangat detail berada pada tingkat ?.....

    BalasHapus

GALIH LARAS PRAKOSO
-
Yogyakarta, Indonesia

SEND ME A MESSAGE