SOLID PRINCIPAL
Hi!! Bagaimana kondisi kalian saat ini? Aku harap kalian semua baik- baik saja, Baik yang masih berusaha untuk melakukan aktivitas pada keadaan pandemi saat ini dan sedang mencegah penularan penyakit dengan tidak beraktivitas di luar rumah. Sebelumnya sesuai judul yang aku buat aku ingin bercerita nih soal dasar-dasar SOLID Principal. Wah apa ini SOLID Principal? Yuk kita bahas
PS : Kalo masi ada yang salah atau kurang dicomment aja ya, biar kita saling belajar dan berkembang yay😁
Sebenarnya apa sih itu SOLID Principal? SOLID Principal ini juga sebenarnya merupakan bagian dari metode OOP yang tujuannya agar kita membuat code program secara baik yang dibuat oleh (kalo penasaran siapa yang buat di buku apa ntr dicek ya gais ehehehe) . Nah pembuatan code yang baik kira" seperti apa sih? Ada nih bisa kalian liat sebagai berikut
- Testable, program dapat ditest / melalui proses test, dan bisa melalui postive/negative test dengan baik,
- Refactorable, mudah kalau ada kebutuhan untuk refactor / memperbaiki flow, menyelipkan fitur baru atau tambahan, dan lain-lain,
- Easy to work with, Kalau ada masalah, dapat dengan mudah pin-point masalahnya di mana, kalau ingin menambahkan fitur kita ga ngerombak yang sudah ada,
- Easy to maintain, mudah untuk proses maintain
Nah kapan sih kita butuh pake metode solid principal ini biar kode yang kita buat jadi lebih baik?
Pada saat program kita kecil, dan user serta developer yang dikit ya bisa aja program dibuat sesuka hati, kalo ada masalah tinggal nanya developer yang bersangkutan. Tapi jika program yang kita buat sudah berkembang menjadi lebih besar dengan fitur" yang bertambah dan lebih kompleks. Apakah kita bisa membuat program sesuka hati kita?
Nah dengan SOLID Principal ini kita diajak untuk mulai mendisiplinkan diri agar kita membuat proses development program yang lebih baik.
Untuk penjelasan lebih lengkap apa si singkatan SOLID itu sendiri?
- (S)ingle Responsibility Principle,
- (O)pen Close Principle,
- (L)iskov Substitution Principle,
- (I)nterface Segregation Principle,
- (D)ependency Inversion Principle
(S)ingle Responsibility Principle
Apa sih gunanya kalau function atau method dipecah-pecah?
- Test nya gampang
- Kalau terjadi error, gampang nemunya
- mau ada ganti proses gampang
- mau ada fitur sama tapi beda (misalnya) engine, gampang juga update nya...
Selama parameter input dan result output nya sama...
Contoh dalam java
public class Book { private String name; private String author; private String text; //constructor, getters and setters // methods that directly relate to the book properties public String replaceWordInText(String word){ return text.replaceAll(word, text); } public boolean isWordInText(String word){ return text.contains(word); } }
Dapat kita pisah untuk model dan method menjadi
model :
public class Book { private String name; private String author; private String text;
public class BookPrinter { // methods for outputting text void printTextToConsole(String text){ //our code for formatting and printing the text } void printTextToAnotherMedium(String text){ // code for writing to any other location.. } }
Pasti kalian bertanya" kenapa sih harus dipecah" pembuatan program
Karena semakin banyak responsibility dalam suatu object/class, maka akan membuat responsibility-responsibility tadi menjadi closed/tightly coupled. Akhirnya kalau ada update atau penambahan fitur or lainnya, maka akan semakin sulit dan dependency terhadap responsibility tersebut jadi semakin tinggi.
(O)pen/Close Principle
Artinya, sebuah class harus terbuka (open) untuk di extends, tapi tertutup (close) untuk modifikasi.
Kalau diterjemahkan , developer yang akan melanjutkan development dikemudian hari, harus tidak dapat mengubah system / class yang sudah ada atau berjalan, tapi juga, dia harus dapat dengan mudah meng-extend class itu.
Keuntungannya dari Open Close Principle ini adalah semakin sedikit kemungkinan modifikasi yang dilakukan terhadap source utama, sehingga kemungkinan terjadinya
Contohnya sebagai berikut
model
public class Guitar { private String make; private String model; private int volume; //Constructors, getters & setters }
Ketika awal kita membuat program kita hanya membutuhkan model Guitar, setelah beberapa saat ternyata kalian membutuhkan fungsi untuk guitar agar guitar yang kalian buat semakin keren maka kalian tinggal extend dr model guitar ini
public class SuperCoolGuitarWithFlames extends Guitar { private String flameColor; //constructor, getters + setters }
Kalau mau ubah, extend dari yg model, sehingga tidak break yang sebelumnya. Jadi class/fungsi yang dependency kesana, tidak break karena perubahan di source yg awalnya.
(L)iskov Substitution Principle
Liskov Substitution Principle (LSP, biar gampang) yang merupakan bagian paling sulit untuk dimengerti jadi pelan - pelan dipahami aja ya gais hehe . jadi LSP kalo gampang ngertinya kalau class a adalah subtype dari class b, kita seharusnya dapat merubah b dengan a tanpa mengganggu jalannya pembuatan program kita
Supaya mudah dipahami, kita pakai contoh saja:
public interface Car { void turnOnEngine(); void accelerate(); }
Diatas , kita mendefinisikan car interface dengan beberapa method yg berarti semua car dapat turnOnEngine(menyalakan mesin) dan Accelerate(menambah laju)
Kita lanjutkan dengan menambahkan method
public class MotorCar implements Car {
private Engine engine;
//Constructors, getters + setters
public void turnOnEngine() {
//turn on the engine!
engine.on();
}
public void accelerate() {
//move forward!
engine.powerOn(1000);
}
}
Sesuai deskripsi program kita dapat menambah kecepatan dan menyalakan mesin
Tapi tunggu, kita sekarang hidup di zaman dengan Mobil elektrik
public class ElectricCar implements Car {
public void turnOnEngine() {
throw new AssertionError("I don't have an engine!");
}
public void accelerate() {
//this acceleration is crazy!
}
}
Dapat diliat kalau dr program kita sebelumnya jika ingin menambahkan fungsi pada class yang lain menjadi lebih mudah. Misalnya kita mau ganti data source, kita ga perlu kuatir dengan parameter atau dengan nama method yg berbeda yang bisa mengubah source code kita ....
(I)nterface Segregation Principle
Interface itu akan men-dikte object yang kita buat, "harus punya method-method ini".
Tapi kadang kita maksain semua method yg kepikiran sama kita dimasukin semua ke interface, atau (kalau anda cukup males untuk membuat interface diawal) interface dibuat sesudah method-method di dalam class yg implemen interface nya ada.
Nahhh ISP (interface segregation principle) itu gunanya adalah utk "memecah" interface tadi menjadi beberapa interface lagi, jadi yang dibutuhkan saja yg akan kita pakai.
public interface BearKeeper { void washTheBear(); void feedTheBear(); void petTheBear(); }
sebagai penjaga kebun binatang, mereka pasti senang untuk mengelus dan memberi makan mereka. namun, mereka juga tau bahaya saat mengelus mereka.Sayangnya karna interface yang dibuat terlalu besar jadinya mereka tidak ada pilihan selain untuk mengimplementasi code jadi petTheBear
Mari kita perbaiki dengan memecah jadi 3 implementasi kecil
public interface BearCleaner { void washTheBear(); } public interface BearFeeder { void feedTheBear(); } public interface BearPetter { void petTheBear(); }
Berkat principal Interface Segregation , kita bebas untuk mengimplementasi implementasi yang kita butuhkan
public class BearCarer implements BearCleaner, BearFeeder { public void washTheBear() { //I think we missed a spot... } public void feedTheBear() { //Tuna Tuesdays... } }
(D)ependency Inversion Principle
Untuk demonstrasi, yuk kita flashback dikit ke taun 98
public class Windows98Machine {}
Tapi apa gunanya komputer tanpa monitor dan keyboard? yuk kita tambah constructor Monitor dan StandartKeyboard
public class Windows98Machine {
private final StandardKeyboard keyboard;
private final Monitor monitor;
public Windows98Machine() {
monitor = new Monitor();
keyboard = new StandardKeyboard();
}
}
Masalah terselesaikan? tidak terlalu. Dengan deklarasi StandartKeyboard dan Monitor dengan new , kita menggabungkan 3 class bersama
tidak hanya kita membuat Windows98Machine lebih sulit untuk ditest, kita juga menghilangkan kemampuan merubah class StandartKeyboard dan Monitor juga
Ayo kita mencoba decouple machine dari standartkeyboard dengan menambah beberapa keyboard interface dan menggunakannya di class kita
public interface Keyboard { }
public class Windows98Machine{
private final Keyboard keyboard;
private final Monitor monitor;
public Windows98Machine(Keyboard keyboard, Monitor monitor) {
this.keyboard = keyboard;
this.monitor = monitor;
}
}
Disini kita menggunakan dependency injection pattern untuk memfasilitasi dengan menambah keyboard depedency ke class Windows98Machine
Kita juga melakukan modifikasi pada class Standart Keyboard untuk implementasi Keyboard interface jadi lebih cocok diinjeksi pada class windows98Machine
public class StandardKeyboard implements Keyboard { }
Sekarang kita sudah decouple beberapa class dan komunikasi melalui abstrak standart Keyboard . Jika kita mau bisa saja kita rubah jadi Mechanical keyboard dengan implementasi yang berbeda.
Dengan menggunakan SOLID Principle, kita bisa dengan mudah untuk mengembangkan sebuah fitur dan meng-implementasi-kan kedalam program kita dengan minimalisir error yang mungkin terjadi. Awal dari sini adalah kita bisa mengembangkan program, apa yang akan kita buat, ketika ada request dadakan (yang sudah kerja pasti sering ngalamin), kita bisa dengan mudah mengerjakannya, tanpa kuatir akan ada error karena dependency ke hal lain. Untuk sementara sampai disini dulu "Teori" mengenai "SOLID", Sekian dari teori SOLID Principal terimakasih
Komentar
Posting Komentar