Anda di halaman 1dari 20

Software Design Principle

Software Design Principle merupakan sebuah pedoman yang dapat kita gunakan untuk
menghindari design yang buruk saat mengembangkan sebuah perangkat lunak. Menurut
Robert C. Martin, terdapat 3 (tiga) karakteristik penting dari design yang buruk yang perlu
kita perhatikan dan sebaiknya dihindari.

Mari kita bahas satu-satu ketiga pedoman tersebut.

Rigidity 

Di mulai dari rigidity atau kekakuan. Rigidity adalah kondisi suatu sistem yang sulit diubah,
bahkan untuk perubahan yang paling sederhana. Saat kita ingin melakukan perubahan,
perubahan tersebut menyebabkan ketergantungan untuk mengubah item lain di dalam suatu
modul. Alhasil, perubahan yang seharusnya dapat dilakukan dalam waktu yang singkat,
malah sebaliknya. Belum lagi dampaknya pada modul-modul lain yang saling berkaitan.

Fragility 

Selanjutnya adalah fragility. Fragility (kerapuhan) masih memiliki keterkaitan dengan


rigidity. Fragility adalah kecenderungan perangkat lunak yang salah di beberapa bagian setiap
kali melakukan perubahan. Seringkali kesalahan terjadi di area yang tidak memiliki hubungan
konseptual dengan area yang diubah. Sehingga jika melakukan perbaikan, kadang takut
timbul kesalahan dengan cara yang tidak terduga. Ketika fragility ada di dalam suatu
perangkat lunak, kemungkinan kesalahan akan meningkat seiring berjalannya waktu.
Perangkat lunak semacam itu tak hanya sulit dipelihara, bahkan sulit juga dipertahankan. Saat
melakukan perbaikan, alih-alih memperbaiki kesalahan yang ada, sebuah sistem akan
menjadi lebih buruk dan menimbulkan lebih banyak masalah.

Immobility 

Terakhir yang harus kita perhatikan dan hindari adalah Imobilitas. Yaitu sebuah
ketidakmampuan untuk menggunakan kembali perangkat lunak dari proyek lain atau bagian-
bagian dari proyek yang sama. Seorang engineer tentu akan mengalami kondisi di mana ia
membutuhkan modul atau sistem yang sebelumnya sudah pernah ditulis atau dibuat oleh
engineer lain. Namun, sering juga terjadi bahwa modul yang dibutuhkan tersebut memiliki
terlalu banyak bobot yang bergantung padanya. Setelah mencoba untuk memisahkan, para
engineer menemukan bahwa pekerjaan dan risiko yang diperlukan untuk memisahkan bagian
yang diinginkan (dari bagian yang tidak diinginkan), terlalu besar untuk ditoleransi. Sehingga
alih-alih menulis ulang (re-write), sang engineer akan menggunakannya kembali untuk
project lain.

Dari penjelasan beberapa pedoman di atas, kita dapat mengetahui lebih dalam mengenai
perbedaan antara architecture dan design pada perangkat lunak. Selain itu, telah dijelaskan
pula tentang bagaimana kita mendefinisikan sebuah design yang buruk dan perlu kita
dihindari.
Pada modul selanjutnya kita akan mempelajari  tentang prinsip SOLID, baik itu definisi,
penjelasan dan contoh studi kasus kapan kita membutuhkannya. Yuk lanjut!
Pada  beberapa modul sebelumnya kita telah belajar memahami Object Oriented
Programming, dari definisi hingga pilar-pilarnya. Kini kita akan masuk ke pembahasan
tentang SOLID ya.

Apa itu SOLID

SOLID merupakan kumpulan dari beberapa principle yang diwujudkan oleh engineer-
engineer yang ahli dibidangnya. SOLID membantu kita  mengembangkan sebuah perangkat
lunak dengan tingkat kekukuhan yang tinggi. Itu goal kita!

Lantas apakah seseorang yang sudah menguasai dan menggunakan OOP perlu mempelajari
SOLID? Tentu saja YA, karena pada dasarnya OOP dan SOLID merupakan 2 (dua) hal yang
berbeda. OOP adalah sebuah paradigma untuk menuliskan program yang sudah diadaptasi
oleh beberapa bahasa pemrograman, sedangkan SOLID merupakan sebuah principle yang
sudah disebutkan sebelumnya. Sampai di sini kita pasti sudah bisa membedakannya ya. 

Berbicara soal paradigma lebih dalam, paradigma sendiri bukanlah sebuah principle yang
mengajarkan tentang bagaimana sebuah tanggung jawab suatu entitas yang berada di dalam
sebuah perangkat lunak. Saat kita sudah berhasil menulis kode dengan mengikuti paradigma
OOP, bukan berarti kita sudah mengikuti design principle yang sudah kita pelajari bersama
dimodul-modul sebelumnya.

Jika kita mengilustasikan prinsip SOLID, seperti inilah gambarnya:  

Ilustrasi di atas menggambarkan bagaimana sekumpulan bola yang disusun sedemikian rupa
dapat menciptakan bentuk yang kukuh. Padahal seperti yang kita ketahui, bola memiliki
bentuk yang sangat mudah untuk bergerak. Analogi serupa dapat kita terapkan saat mengetik
kode. Dalam mengembangkan sebuah perangkat lunak, jika kita bisa menuliskan kode
dengan bentuk dan ukuran yang sama seperti halnya kumpulan bola di atas, kita pun dapat
menciptakan sebuah sistem yang kukuh. Denga terciptanya sistem yang kukuh, kita dapat
lebih mudah dan leluasa mengganti komponen dan memperluas sistem tanpa adanya
gangguan.

Tujuan SOLID

Sudah paham kan penjelasan dari ilustrasi di atas? Kita jadi paham bahwa dengan mengikuti
prinsip SOLID, kode yang kita buat dapat dengan mudah diekstensi (extended) dan
dipertahankan (maintained).

Prinsip SOLID bukanlah suatu hukum atau aturan tertentu yang wajib kita patuhi, melainkan
sebuah prinsip yang dimaksudkan untuk membantu kita dalam menuliskan kode yang rapi.
Bagaimana hal itu dapat diwujudkan? Berikut adalah tujuan dari prinsip SOLID dalam
pembuatan struktur mid-level perangkat lunak:

 Toleran terhadap perubahan


 Mudah dipahami
 Komponen dasar dapat digunakan kembali dalam bentuk software system lainnya

Istilah mid-level yang merujuk pada prinsip SOLID ini diterapkan oleh engineer yang bekerja
pada level module. Prinsip ini diterapkan tepat di atas level kode. Manfaatnya, ia dapat
membantu menentukan jenis struktur perangkat lunak yang digunakan dalam modul dan
komponen. Setelah komponen tersebut dapat kita desain dengan baik menggunakan prinsip
SOLID, maka selanjutnya kita dapat melanjutkan ke dalam prinsip-prinsip arsitektur tingkat
tinggi (high-level architecture). 

Di modul berikutnya kita akan sama-sama belajar lebih dalam lagi tentang masing-masing
principle yang menjadi bagian dari SOLID itu sendiri.
Kita sudah belajar memahami Object Orientation Programming dan Software Design
Principle. Akhirnya kita sampai juga di modul yang membahas masing-masing prinsip bagian
dari SOLID, lebih dalam.

Single Responsibility Principle (SRP)

Kita mulai dari Single Responsibility Principle. Ia merupakan sebuah principle yang relatif
mudah diterapkan dalam pengembangan perangkat lunak. Sederhannya, principle ini
digunakan untuk mengatur tanggung jawab dari sebuah entitas yang berada di dalam sebuah
proyek dalam hal ini adalah sebuah class.

Tanggung jawab (responsibility) berarti bahwa jika suatu class punya 2 (dua) fungsionalitas
yang tak miliki keterkaitan untuk melakukan suatu perubahan, maka kita harus membagi
fungsionalitas yang berbeda tersebut dengan cara memisahkannya menjadi dua class yang
berbeda. 

Maka dari itu, setiap class yang sudah dipisahkan berdasarkan fungsionalitasnya hanya akan
menangani satu tanggung jawab. Lebih lanjut, jika kita melakukan perubahan tanggung
jawab, kita tinggal fokus pada masing-masing class yang sudah dipisahkan tersebut. 

Apa tujuan menerapkan Single Responsibility? Ketika kita ingin melakukan perubahan pada
sebuah class yang memiliki tanggung jawab yang banyak, perubahan yang akan dilakukan
berpotensi untuk mempengaruhi fungsionalitas dan tanggung jawab lain yang saling
berkaitan di dalam class tersebut.

Single Responsibility Principle adalah prinsip yang sederhana dan intuitif, tetapi dalam
praktiknya terkadang sulit untuk memperbaikinya. Untuk itu, mari kita lanjut ke modul
selanjutnya untuk mengetahui seperti apa penerapannya pada sebuah contoh kasus. Ayo!
Setelah selesai dengan Single Responsibility Principle, mari kita lanjut ke aturan berikutnya
yaitu sebuah entitas perangkat lunak seperti class, property, dan function. Mereka adalah
entitas untuk ditambahkan tetapi tidak untuk dimodifikasi yaitu Open/Close Principle.
Seperti apa detail aturannya?

Open/Close Principle (OCP)

Pada Tahun 1988, seorang profesor asal Perancis, Bertrand Meyer menulis sebuah buku yang
berjudul  Object Oriented Software Construction. Di dalamnya terdapat sebuah aturan yang
mengatur di mana sebuah artefak perangkat lunak harus terbuka untuk ditambahkan tetapi
tertutup untuk dimodifikasi. Aturan tersebut kemudian ditulis lagi pada sebuah artikel yang
berjudul The Open-Closed Principle oleh Robert C. Martin pada tahun 1996.

Lantas apa yang dimaksud dengan terbuka untuk ditambahkan dan tertutup untuk
dimodifikasi? Jangan bingung. Terbuka untuk ditambahkan adalah keadaan ketika sebuah
sistem dapat ditambahkan dengan spesifikasi baru yang dibutuhkan. Sedangkan tertutup
untuk dimodifikasi adalah agar ketika ingin menambahkan spesifikasi baru, kita tidak perlu
mengubah atau memodifikasi sistem yang telah ada.

Aturan ini sekilas terlihat bertentangan satu sama lain, yah? Namun tak usah khawatir, karena
saat kita bisa mengatur dependensi sistem dengan baik dan benar, dengan mudahnya aturan
tersebut dapat kita capai. Secara umum, penggunaan aturan open/close diterapkan dengan
memanfaatkan interface dan abstraksi kelas daripada menggunakan sebuah kelas konkret.
Penggunaan interface dan abstraksi kelas bertujuan agar dapat mudah diperbaiki setelah
pengembangan tanpa harus mengganggu kelas yang mewarisi dan ketika ingin membuat
fungsionalitas baru, cukup dengan membuat kelas baru dan mewarisi interface atau abstraksi
tersebut.

Penasaran seperti apa penerapannya? Mari melangkah ke modul berikutnya.


Setelah selesai dengan 2 (dua) aturan sebelumnya, apakah kini Anda sudah punya gambaran
untuk diterapkan di dalam proyek garapan Anda? Pastinya iya, agar kode yang sudah kita
tulis bisa dikembangkan lebih lanjut tanpa halangan berarti.

Liskov Substitution Principle (LSP)

Oke, kita lanjut ke aturan berikutnya yaitu Liskov Substitution Principle.  Aturan ini
disampaikan pada pembukaan sebuah acara oleh Barbara Liskov. Beliau menyampaikan
pernyataan sebagai berikut “if for each object o1 of type S there is an object o2 of type T such
that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is
substituted for o2 then S is a subtype of T”. 

Sederhanannya, Liskov’s substitution adalah aturan yang berlaku untuk hirarki pewarisan.
Hal ini mengharuskan kita untuk mendesain kelas-kelas yang kita miliki sehingga
ketergantungan antar klien dapat disubstitusikan tanpa klien mengetahui tentang perubahan
yang ada. Oleh karena itu, seluruh SubClass setidaknya dapat berjalan dengan cara yang
sama seperti SuperClass-nya.

Untuk menjadikan sebuah kelas benar-benar menjadi SubClass, kelas tersebut tidak hanya
wajib untuk menerapkan fungsi dan properti dari SuperClass, melainkan juga harus memiliki
perilaku yang sama dengan SuperClass-nya. Untuk mencapainya, terdapat beberapa aturan
yang harus dipatuhi. Mari kita bahas satu per satu.

Contravariant dan Covariant

Aturan pertama, SubClass harus memiliki sifat contravariant dan covariant.


Contravariant adalah kondisi di mana parameter dari sebuah fungsi yang berada pada
SubClass harus memiliki tipe dan jumlah yang sama dengan fungsi yang berada pada
SuperClass-nya. Sedangkan Covariant adalah kondisi pengembalian nilai dari fungsi yang
berada pada SubClass dan SuperClass.

preconditions dan postconditions

Selanjutnya adalah aturan preconditions dan postconditions. Ini merupakan tindakan yang
harus ada sebelum atau sesudah sebuah proses dijalankan. Contohnya, ketika kita ingin
memanggil sebuah fungsi yang digunakan untuk membaca data dari database, terlebih dahulu
kita harus memastikan database tersebut dalam keadaan terbuka agar proses dapat dijalankan.
Ini disebut sebagai precondition. Sedangkan postcondition, contohnya saat proses baca tulis
di dalam database telah selesai, kita harus memastikan database tersebut sudah tertutup.

Invariant

Berikutnya adalah invariant. Dalam pembuatan sebuah SubClass, SubClass tersebut harus
memiliki invarian yang sama dengan SuperClass-nya. Invarian sendiri adalah penjelasan
dari kondisi suatu proses yang benar sebelum proses tersebut dimulai dan tetap benar
setelahnya.

Constraint

Terakhir, aturan tentang constraint dari sebuah SubClass. Secara default, SubClass dapat
memiliki fungsi dan properti dari SuperClass-nya. Selain itu, kita juga dapat menambahkan
member baru di dalamnya. Constraint di sini adalah pembatasan yang ditentukan oleh
SuperClass terhadap perubahan keadaan sebuah obyek. Sebagai contoh misal SuperClass
memiliki obyek yang memiliki nilai tetap, maka SubClass tidak diijinkan untuk mengubah
keadaan dari nilai obyek tersebut.

Nah, setelah tahu beberapa aturan di atas, lantas seperti apa penerapannya? Ayo kita pelajari
di modul berikutnya.
Setelah selesai dengan 2 (dua) aturan sebelumnya, apakah kini Anda sudah punya gambaran
untuk diterapkan di dalam proyek garapan Anda? Pastinya iya, agar kode yang sudah kita
tulis bisa dikembangkan lebih lanjut tanpa halangan berarti.

Liskov Substitution Principle (LSP)

Oke, kita lanjut ke aturan berikutnya yaitu Liskov Substitution Principle.  Aturan ini
disampaikan pada pembukaan sebuah acara oleh Barbara Liskov. Beliau menyampaikan
pernyataan sebagai berikut “if for each object o1 of type S there is an object o2 of type T such
that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is
substituted for o2 then S is a subtype of T”. 

Sederhanannya, Liskov’s substitution adalah aturan yang berlaku untuk hirarki pewarisan.
Hal ini mengharuskan kita untuk mendesain kelas-kelas yang kita miliki sehingga
ketergantungan antar klien dapat disubstitusikan tanpa klien mengetahui tentang perubahan
yang ada. Oleh karena itu, seluruh SubClass setidaknya dapat berjalan dengan cara yang
sama seperti SuperClass-nya.

Untuk menjadikan sebuah kelas benar-benar menjadi SubClass, kelas tersebut tidak hanya
wajib untuk menerapkan fungsi dan properti dari SuperClass, melainkan juga harus memiliki
perilaku yang sama dengan SuperClass-nya. Untuk mencapainya, terdapat beberapa aturan
yang harus dipatuhi. Mari kita bahas satu per satu.

Contravariant dan Covariant

Aturan pertama, SubClass harus memiliki sifat contravariant dan covariant.


Contravariant adalah kondisi di mana parameter dari sebuah fungsi yang berada pada
SubClass harus memiliki tipe dan jumlah yang sama dengan fungsi yang berada pada
SuperClass-nya. Sedangkan Covariant adalah kondisi pengembalian nilai dari fungsi yang
berada pada SubClass dan SuperClass.

preconditions dan postconditions

Selanjutnya adalah aturan preconditions dan postconditions. Ini merupakan tindakan yang
harus ada sebelum atau sesudah sebuah proses dijalankan. Contohnya, ketika kita ingin
memanggil sebuah fungsi yang digunakan untuk membaca data dari database, terlebih dahulu
kita harus memastikan database tersebut dalam keadaan terbuka agar proses dapat dijalankan.
Ini disebut sebagai precondition. Sedangkan postcondition, contohnya saat proses baca tulis
di dalam database telah selesai, kita harus memastikan database tersebut sudah tertutup.

Invariant

Berikutnya adalah invariant. Dalam pembuatan sebuah SubClass, SubClass tersebut harus
memiliki invarian yang sama dengan SuperClass-nya. Invarian sendiri adalah penjelasan
dari kondisi suatu proses yang benar sebelum proses tersebut dimulai dan tetap benar
setelahnya.

Constraint

Terakhir, aturan tentang constraint dari sebuah SubClass. Secara default, SubClass dapat
memiliki fungsi dan properti dari SuperClass-nya. Selain itu, kita juga dapat menambahkan
member baru di dalamnya. Constraint di sini adalah pembatasan yang ditentukan oleh
SuperClass terhadap perubahan keadaan sebuah obyek. Sebagai contoh misal SuperClass
memiliki obyek yang memiliki nilai tetap, maka SubClass tidak diijinkan untuk mengubah
keadaan dari nilai obyek tersebut.

Nah, setelah tahu beberapa aturan di atas, lantas seperti apa penerapannya? Ayo kita pelajari
di modul berikutnya.
Setelah Liskov Substitution, prinsip selanjutnya yang akan kita pelajari adalah Interface
segregation. Prinsip Interface Segregation adalah salah satu dari prinsip yang dikemukakan
oleh Robert C.Martin dalam bukunya yang berjudul Design Principle. Meskipun prinsip-
prinsip tersebut sudah beberapa tahun usianya, prinsip-prinsip ini tetap penting seperti saat
pertama kali ia rilis. 

Interface Segregation Principle (ISP)

Prinsip ini sendiri bertujuan untuk mengurangi jumlah ketergantungan sebuah class terhadap
interface class yang tidak dibutuhkan. Faktanya, class memiliki ketergantungan terhadap
class lainnya. Jumlah ketergantungan dari fungsi pada sebuah interface class yang dapat
diakses oleh class tersebut harus dioptimalkan atau dikurangi. Mengapa penting? Terkadang
ketika kita membuat sebuah class dengan jumlah fungsi dan properti yang banyak, class lain
yang bergantung pada class tersebut hanya membutuhkan satu atau dua fungsi dari class
tersebut. Ketergantungan antar class akan semakin bertambah seiring bertambahnya jumlah
fungsi dan properti dari class yang dibutuhkan. Lalu bagaimana cara mengatasinya? 

Pada saat kita membuat sebuah sistem, pasti kita pernah membuat sebuah class yang
memiliki atau mengimplementasikan beberapa public interface dan interface-interface
tersebut juga digunakan dan di implementasi oleh class lainnya dalam sistem kita. class-class
yang kita buat ini terkadang hanya membutuhkan beberapa fungsi yang ada pada interface
tersebut sehingga menurut aturan prinsip interface segregation hal ini kurang baik. Tapi
tenang, ketika prinsip interface segregation diterapkan, setiap class-class akan
mengimplementasi beberapa interface class yang lebih kecil sesuai dengan fungsi-fungsi
yang dibutuhkan class-class tersebut. 

Hal ini berarti bahwa class-class yang saling bergantung dapat berkomunikasi dengan
menggunakan interface yang lebih kecil, mengurangi ketergantungan pada fungsi-fungsi yang
tidak digunakan dan mengurangi coupling. Dengan menggunakan interface yang lebih kecil
akan memudahkan dalam implementasi, meningkatkan fleksibilitas dan juga kemungkinan
untuk digunakan kembali (reuse).

Menarik sekali bukan jika kita berhasil menerapkan prinsip interface segregation dalam
sistem kita? Yuk kita lanjutkan belajarnya ke studi kasus pada modul selanjutnya.
Setelah kita membahas mengenai empat prinsip sebelumnya, kini kita akan membahas
mengenai prinsip terakhir dari S.O.L.I.D, yaitu Prinsip Dependency Inversion. Pada prinsip
Dependency Inversion terdapat dua pernyataan atau aturan yang perlu kita ketahui, yang
pertama adalah high-level module tidak diperbolehkan untuk bergantung pada low-level
module. Keduanya harus bergantung pada abstraction. Pernyataan yang kedua, abstraksi
tidak diperbolehkan untuk bergantung pada detail. Detail harus bergantung pada abstraksi.

Dependency Inversion Principle (DIP)

Prinsip Dependency Inversion hampir sama dengan konsep layering dalam aplikasi, di mana
low-level modules bertanggung jawab dengan fungsi yang sangat detail dan high-level
modules menggunakan low-level classes untuk mencapai tugas yang lebih besar. Hal ini bisa
dicapai dengan bergantung pada sebuah abstraksi, ketika ada ketergantungan antar kelas
seperti interface, daripada referensi langsung ke kelas lainnya.

Apa yang dimaksud dengan high-level modules dan low-level modules? Agar lebih mudah
memahaminya, kita dapat mengkategorikan kelas-kelas menjadi sebuah hirarki. High-level
modules adalah kelas-kelas yang berurusan dengan kumpulan-kumpulan fungsionalitas. Pada
hirarki tertinggi terdapat kelas-kelas yang mengimplementasikan aturan bisnis sesuai dengan
desain yang telah ditentukan. Low-level modules bertanggung jawab pada operasi yang lebih
detail. Pada level terendah memungkinkan modul ini untuk bertanggung jawab dalam
menulis informasi ke database atau menyampaikan pesan ke sistem operasi. 

Berbeda dengan modul-modul sebelumnya, kita akan memulai contoh penerapan dari
Dependency Inversion dengan penjelasan singkat dari hierarki kelas di bawah ini.

Hirarki di atas adalah gambaran fitur sebuah transaksi yang digunakan untuk berinterasi
dengan database. Jika kita perhatikan, di dalam hirarki di atas terdapat class PaymentService
yang digunakan untuk melakukan pembayaran dan class MySQLDatabase yang
bertanggung jawab menyimpan data tersebut ke dalam database. Pada sistem ini juga akan
terdapat fungsi-fungsi untuk menambah atau menghapus data pembayaran. Untuk melakukan
pembayaran kita akan membutuhkan class yang merupakan high-level yaitu class
PaymentService. 
Jika kita melihat penerapan pada class tersebut, permasalahan yang ada adalah class tersebut
bergantung pada class database dan memiliki referensi langsung pada class tersebut sebagai
propertinya. Akibatnya, mustahil kita mengganti tipe data dari class tersebut atau ketika kita
ingin menambahkan database baru. Kecuali, class-class yang akan kita tambahkan merupakan
SubClass dari class MySQLDatabase. 

Namun, dengan menambahkan class baru tersebut, kita dapat menyalahi prinsip Liskov
Substitution. Kenapa? Sebabnya, kita membutuhkan perubahan lagi pada class
PaymentService yang berarti kita menyalahi aturan lainnya yaitu Open/Close Principle.

Masalah lainnya yang akan timbul adalah ketika kita membutuhkan perubahan pada class
MySQLDatabase, di mana perubahan yang ada pada class tersebut dapat mempengaruhi class
di atasnya yaitu PaymentService. Hal ini juga memungkinkan kita untuk mengubah class-
class lainnya yang berada pada hierarki di atasnya, ketika sistem kita terus berkembang,
permasalahan ini akan tetap terus ada dan semakin membuat kita kesusahan dalam
mengembangkan sistem yang kukuh.

Dengan menerapkan prinsip Dependency Inversion, kita dapat menyelesaikan permasalahan-


permasalahan ini dengan menghapus ketergantungan langsung antar class. Bagaimana
caranya? Kita dapat mengubah ketergantungan antar class dengan membuat class-class
tersebut bergantung pada abstraksi, seperti interface atau abstract class. Pada lower-level,
class-class yang ada dapat mengimplementasikan interfaces, atau mewariskan fungsi-fungsi
dari abstract class. Dengan begitu, perubahan yang ada pada class-class di lower-level tidak
akan mempengaruhi hirarki di atasnya, dengan syarat kita tidak mengubah abstraksi yang
dibutuhkan.

Manfaat lainnya dari penggunaan atau penerapan prinsip ini dapat meningkatkan kekukuhan
dan fleksibilitas dari sistem yang kita kembangkan. Tanpa penerapan prinsip
Dependency,Inversion, hanya class-class lower-level saja yang mudah digunakan kembali.

Agar lebih jelas memahami contoh di atas, mari kita coba mengubah contoh kode yang
menyalahi aturan tersebut dan menjelaskan perubahannya agar sesuai dengan prinsip
Dependency Inversion. Contoh di bawah ini merupakan kode dari hierarki pada class di atas:

 Kotlin

 Java

 Swift

 JavaScript

 Dart

1. class PaymentService {

2.     

3.     private val database: MySQLDatabase = MySQLDatabase()

4.     
5.     fun paymentIsValid() {

6.        // Implementation code 

7.     }

8.     

9.     fun openDatabase() {

10.        // Implementation code 

11.     }

12.     

13.     fun addNewPayment() {

14.        // Implementation code 

15.     }

16.     

17.     fun removePaymentByID() {

18.        // Implementation code 

19.     }

20.     

21.     fun updatePaymentByID() {

22.        // Implementation code 

23.     }

24. }

25.  

26. class MySQLDatabase {

27.     

28.     fun insert() {

29.         // Implementation code

30.     }

31.     

32.     fun update() {


33.         // Implementation code

34.     }

35.     

36.     fun delete() {

37.         // Implementation code

38.     }

39. }

Untuk memperbaiki contoh kode di atas agar sesuai dengan prinsip Dependency Inversion,
kita dapat menghapus ketergantungan langsung class PaymentService terhadap class
MySQLDatabase. Kita akan menambahkan abstract class baru sehingga nantinya ketika kita
menambahkan implementasi baru untuk database, kita hanya akan mewariskan dari class
Database. Sehingga hierarki dari kode yang akan kita perbaiki menjadi seperti berikut.

Class abstract yang akan kita tambahkan, yaitu class Database, akan berada pada high-level
dari hierarki class. Sedangkan class MySQLDatabase dan MongoDatabase akan menjadi
SubClass dari class tersebut sehingga tidak ada ketergantungan langsung pada class yang
menjadi implementasi database. Hal ini akan memudahkan kita untuk menambahkan atau
mengganti kode pada class di bawahnya tanpa mempengaruhi class pada hirarki di atasnya.
Untuk lebih jelasnya kita dapat melihat implementasinya pada potongan kode berikut:

 Kotlin

 Java

 Swift

 JavaScript

 Dart

1. class PaymentService (val database: Database) {

2.     

3.     fun paymentIsValid() {

4.        // Implementation code 

5.     }

6.     

7.     fun openDatabase() {

8.        // Implementation code 

9.     }

10.     

11.     fun addNewPayment() {

12.        // Implementation code 

13.     }

14.     

15.     fun removePaymentByID() {

16.        // Implementation code 

17.     }

18.     

19.     fun updatePaymentByID() {

20.        // Implementation code 


21.     }

22. }

23.  

24. abstract class Database {

25.     abstract fun insert()

26.     abstract fun update()

27.     abstract fun delete()

28. }

29.  

30. class MySQLDatabase : Database() {

31.  

32.     override fun insert() {

33.         // Implementation code

34.     }

35.     

36.     override fun update() {

37.         // Implementation code

38.     }

39.     

40.     override fun delete() {

41.         // Implementation code

42. }

43. }

44.  

45. class MongoDatabase : Database() {

46.

47.     override fun insert() {

48.         // Implementation code


49.     }

50.     

51.     override fun update() {

52.         // Implementation code

53.     }

54.     

55.     override fun delete() {

56.         // Implementation code

57.     }

58. }

Dependency Inversion Principle merupakan prinsip ke-5 dan terakhir dari S.O.L.I.D. Dalam
prinsip ini dikenalkan abstraksi sebagai antarmuka antara komponen yang memilik hierarki
tinggi (higher-level) dan komponen yang memiliki hierarki rendah (lower-level) untuk
menghilangkan ketergantungan antara kedua hierarki tersebut.

Setelah mempelajari semua modul hingga tahap ini, Anda dapat banyak pengetahuan mulai
dari pendalam Object Orientation Programming sampai pengertian dan studi kasus dari
beberapa prinsip-prinsip SOLID. Modul selanjutnya adalah modul paling seru! Anda akan
menyelesaikan exam untuk menguji seberapa paham materi-materi yang sudah dipelajari.
Sudah siap? Baca kembali materi, jika belum.

agar paham penerapannya pada sebuah studi kasus.

Anda mungkin juga menyukai