The Dispensables
"Dispensable" adalah smell yang terjadi jika ada bagian-bagian code yang kurang berguna dan tidak dibutuhkan. Ketiadaannya akan membuat code lebih bersih, efisien, dan lebih mudah untuk dipahami.
"Dispensable" adalah smell yang terjadi jika ada bagian-bagian code yang kurang berguna dan tidak dibutuhkan. Ketiadaannya akan membuat code lebih bersih, efisien, dan lebih mudah untuk dipahami.
"Apa salahnya sih CTRL+C CTRL+V berkali kali? Toh tinggal edit dikit aja codenya masih bisa jalan..."
Smell ini terjadi jika terdapat bagian code yang sama atau mirip.
Biasanya smell ini terjadi jika beberapa programmer kerja dalam part yang berbeda dalam program yang sama. Dikarenakan tugas mereka berbeda, mereka bisa tidak sadar bahwa ternyata code yang mereka buat sudah dibuat sama anggota tim mereka.
Tahukah kamu? Kita bisa menggunakan Rule of Three sebagai patokan yaitu jika ada bagian code yang sudah di copy-paste tiga kali, maka sudah menjadi lampu merah untuk segera dilakukan refactor.
Lihatlah class Foo
di bawah ini:
Pada function bar()
, bax()
, dan qux()
, terdapat banyak bagian method yang sama. Oleh karena itu perlu direfactor agar tidak terjadi duplikasi code.
Lakukan Extract Method pada beberapa bagian dalam code. Seperti for
yang sama dapat diextract ke method baru dan tambahkan parameter variable dalam method tersebut agar kita bisa mengimplementasikan method untuk print Bar, Baz, dan Quz.
Dapat digunakan jika duplicate code ada di sebuah constructor.
Dapat digunakan jika sebuah ada duplicate code yang mirip namun tidak 100% identik.
Jika ada dua method yang melakukan hal yang sama tetapi menggunakan algoritma yang berbeda, pilihlah algoritma terbaik dan terapkan Substitute Algorithm.
Jika terdapat sejumlah besar conditional expression yang hadir dan melakukan kode yang sama (hanya berbeda dalam kondisinya), gabungkan operator-operasi ini menjadi satu kondisi menggunakan Consolidate Conditional Expression.
Jika kode yang sama dilakukan di semua cabang dari sebuah conditional expression, tempatkan kode yang identik di luar condition tree dengan menggunakan Consolidate Duplicate Conditional Fragment.
"Lagi ngoding kok ditinggal? Gapapa donk bikin class yang isinya buat print doank?"
Smell ini terjadi apabila dalam satu class isinya dikit atau hanya berisi satu function yang minim.
Smell ini bisa terjadi karena refactoring. Jadi awalnya class ini didesain sebagai class yang fully functional, namun karena terdapat beberapa smell maka direfactoring dan menjadi class yang isinya minim.
Sebuah project mempunyai class Price
dan PriceValidator
. Di bawah ini adalah isi class PriceValidator
:
Class tersebut hanya mempunyai satu function untuk validasi harga. Maka dari itu, class ini termasuk lazy class.
Function validate
dapat digabung ke class Price
dan diberi nama yang sesuai yaitu isPriceValid
. Setelah dipindahkan, class PriceValidator
dapat dihapus.
Misalnya ada subclass yang isinya sama seperti superclassnya, maka dapat digabungkan saja agar tidak terjadi lazy class.
"Class kok isinya data doank? Mending belajar data struct aja kalau mau muat data doank!!"
Smell ini terjadi jika ada kelas yang isinya cuman field dan setter getter saja. Dia disebut sebagai dumb data holders sehingga bisa dipertimbangkan untuk dibuang dengan cara digabung dengan class lain saja.
Ketika sebuah produk baru di awal-awal code, wajar saja jika banyak class yang belum memiliki behavior (baru berisi data saja). Namun, apabila produknya sudah semakin berkembang dan masih ada class yang hanya berisi setter dan getter, maka lebih baik direfactor saja.
Lihatlah class FullName
di bawah ini:
Pada class tersebut hanya terdapat data dan setter getter untuk firstName
dan lastName
saja.
Refactor code smell tersebut dengan memindahkan field firstName
dan lastName
ke class User
. Kemudian hapus class FullName
sehingga seluruh data mengenai user hanya disimpan di class User
.
Jika ada bidang-bidang dalam sebuah kelas yang dapat diakses secara langsung dari luar kelas (public), lebih baik kita sembunyikan bidang-bidang tersebut dan memberikan akses ke mereka melalui metode getter dan setter.
Dapat digunakan untuk data yang disimpan dalam koleksi (seperti array).
"Kasian banget, code udh dibuat tapi malah didiemin aja. Lama-lama mati rasa deh"
Smell yang terjadi jika ada variable/parameter/field/class/metode yang tidak lagi terpakai.
Misalnya ada perubahan requirements dalam sebuah method. Setelah membuat code dengan requirements yang baru, code yang lama tetap dibiarkan (tidak dihapus).
Sebagai contoh, pada class PriceCalculator
terdapat function calculate
untuk menghitung diskon. Requirement awalnya adalah akan diberikan diskon 10% jika harga kurang dari 10.000 dan jika lebih maka akan diberikan diskon 20%. Namun, terjadi perubahan requirement yakni diskon akan diberikan sebesar 15% saja secara rata tanpa minimal harga.
Bisa dilihat pada code diatas, bahwa programmer tidak menghapus requirement yang pertama. Hal ini termasuk dead code karena meskipun bagian tersebut dijalankan, variable discountPrice
hanya akan diambil dari requirement kedua.
Bagian requirement yang pertama dapat dihapus saja.
Dapat digunakan untuk menghapus class yang tidak berguna.
Dapat digunakan untuk menggabungkan subclass dengan superclass.
Dapat digunakan untuk menghapus parameter yang tidak dibutuhkan dalam sebuah method.
"Hadeh sok banget sih pake buat class tambahan segala. Emangnya dengan buat code tambahan nantinya bakal kepake? Yang ada nanti malah buang-buang waktu dan tenaga doank!!"
Smell ini terjadi jika ada class, method, field, atau parameter yang sudah dibuat padahal belum dipakai atau sebetulnya tidak dibutuhkan dalam requirement.
Biasanya hal ini terjadi ketika programmer berspekulasi bahwa projectnya akan membutuhkan code itu. Namun, setelah produk berjalan, bagian code ini ternyata tidak dibutuhkan. Hal ini menjadi masalah karena code menjadi lebih sulit dibaca untuk hal yang tidak perlu.
Salah satu prinsip extreme programming (XP) yang terkenal adalah You Aren’t Gonna Need It (YAGNI). Disarankan oleh XP untuk tidak menambahkan fungsionalitas sampai benar-benar diperlukan.
Contohnya ada sebuah project dimana requirementnya adalah price bisa memiliki Currency antara USD atau IDR. Namun, programmer berspekulasi bahwa IDR dan USD termasuk dalam kurs jenis tradisional dan nantinya akan ada kurs jenis digital. Sehingga programmer membuat abstract class Traditional
dan Digital
yang merupakan turunan dari class Currency
. Class IDR
dan USD
akan menjadi turunan dari class Traditional
sedangkan class Digital
akan menjadi parent class dari kurs jenis digital.
Class Digital
sebenarnya tidak dibutuhkan karena tidak termasuk dalam requirement. Maka class ini dapat dihapus saja.
Selain class Digital
, class Traditional
juga dapat dihapus. Lakukan Collapse Hierarchy dengan membuat class IDR
dan class USD
menjadi turunan langsung dari class Currency
.
Dapat digunakan untuk menghapus kelas yang tidak lagi diperlukan dan menggabungkan fungsionalitasnya langsung ke dalam kelas yang memanggilnya.
Dapat digunakan untuk menghapus method yang tidak digunakan.
Dapat digunakan untuk menghapus parameter yang tidak dibutuhkan dalam sebuah method.
Comments
Penjelasan
Smell ini terjadi ketika ada terlalu banyak komen dalam sebuah code.
Tahukah kamu? Kalau dalam pembuatan nama variable, method, class, maupun interface, sudah harus bisa menjelaskan apa isi dari masing-masing tindakannya. Begitu juga logic flow di dalam function harus dapat dimengerti oleh programmer lainnya tanpa memerlukan comment yang panjang.
Comment masih dapat digunakan untuk dokumentasi API seperti di bawah ini
Namun terdapat beberapa kondisi dimana comment dianggap sebagai smell. Sebagai contoh, lihatlah class
MenuPrinter
yang dicantumkan di bawah ini:Terdapat banyak komentar pada class
MenuPrinter
dan functionprintMenu()
.Di atas function
printMenu()
tertulis komen bahwa function ini dapat melakukan print, scan, dan return hasil scan. Sedangkan nama functionnya hanyaprintMenu()
. Hal ini dapat menyesatkan programmer lain karena penamaan function tidak sesuai dengan fungsinya.Penyelesaian
Lakukan Extract Method pada bagian-bagian dalam fungsi agar dapat membedakan tujuan function yang satu dengan yang lainnya dengan jelas. Kemudian Rename Method pada function
printMenu()
menjadiprintMenuAndGetInput()
.Treatment lain yang bisa dilakukan pada Comments:
Jika sebuah comment ditujukan untuk menjelaskan sebuah ekspresi yang kompleks, ekspresi tersebut seharusnya dibagi menjadi beberapa subekspresi dan hasil dari subekspresi tersebut disimpan dalam variable self-explanatory yang berbeda-beda.
Dapat digunakan jika sebuah bagian dalam code memerlukan rules assert agar code dapat berjalan.