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.

Comments

Penjelasan

"Niatan baik malah dianggap sampah. Emang kalian jahat banget ya? Aku cuman ingin membuat petunjuk disini.."

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 function printMenu().

Di atas function printMenu() tertulis komen bahwa function ini dapat melakukan print, scan, dan return hasil scan. Sedangkan nama functionnya hanya printMenu(). 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() menjadi printMenuAndGetInput().

Treatment lain yang bisa dilakukan pada Comments:

  • Extract Variable
  • 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.

  • Introduce Assertion
  • Dapat digunakan jika sebuah bagian dalam code memerlukan rules assert agar code dapat berjalan.

Duplicate Code

Penjelasan

"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.

Penyelesaian

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.

Treatment lain yang bisa dilakukan pada Duplicate Code:

  • Pull Up Constructor Body.
  • Dapat digunakan jika duplicate code ada di sebuah constructor.

  • Form Template Method
  • Dapat digunakan jika sebuah ada duplicate code yang mirip namun tidak 100% identik.

  • Substitute Algorithm
  • Jika ada dua method yang melakukan hal yang sama tetapi menggunakan algoritma yang berbeda, pilihlah algoritma terbaik dan terapkan Substitute Algorithm.

  • Consolidate Conditional Expression
  • 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.

  • Consolidate Duplicate Conditional Fragment
  • 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.

Lazy Class

Penjelasan

"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.

Penyelesaian

Function validate dapat digabung ke class Price dan diberi nama yang sesuai yaitu isPriceValid. Setelah dipindahkan, class PriceValidator dapat dihapus.

Treatment lain yang bisa dilakukan pada Lazy Class:

  • Collapse Hierarchy
  • Misalnya ada subclass yang isinya sama seperti superclassnya, maka dapat digabungkan saja agar tidak terjadi lazy class.

Data Class

Penjelasan

"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.

Penyelesaian

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.

Treatment lain yang bisa dilakukan pada Data Class:

  • Encapsulate Field
  • 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.

  • Encapsulate Collection
  • Dapat digunakan untuk data yang disimpan dalam koleksi (seperti array).

Dead Code

Penjelasan

"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.

Penyelesaian

Bagian requirement yang pertama dapat dihapus saja.

Treatment lain yang bisa dilakukan pada Dead Code:

  • Inline Class
  • Dapat digunakan untuk menghapus class yang tidak berguna.

  • Collapse Hierarchy
  • Dapat digunakan untuk menggabungkan subclass dengan superclass.

  • Remove Parameter
  • Dapat digunakan untuk menghapus parameter yang tidak dibutuhkan dalam sebuah method.

Speculative Generality

Penjelasan

"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.

Penyelesaian

Selain class Digital, class Traditional juga dapat dihapus. Lakukan Collapse Hierarchy dengan membuat class IDR dan class USD menjadi turunan langsung dari class Currency.

Treatment lain yang bisa dilakukan pada Speculative Generality:

  • Inline Class
  • Dapat digunakan untuk menghapus kelas yang tidak lagi diperlukan dan menggabungkan fungsionalitasnya langsung ke dalam kelas yang memanggilnya.

  • Inline Method
  • Dapat digunakan untuk menghapus method yang tidak digunakan.

  • Remove Parameter
  • Dapat digunakan untuk menghapus parameter yang tidak dibutuhkan dalam sebuah method.