Couplers
Smell → Martin Fowler Code Smells → Couplers
Semua smell di dalam grup ini berkaitan dengan coupling yang tinggi. Meski tidak mempengaruhi jalannya project, namun tingginya coupling (dan rendahnya cohesion) akan menyusahkan class lain dan secara tidak langsung mengakibatkan developer sulit menangani perubahan modul meski dengan perubahan paling kecil sekalipun karena dependensi antar class yang tinggi.
Seperti yang telah Anda pelajari di matakuliah Program Design Methods di semester sebelumnya, code yang baik memiliki coupling yang dibuat serendah mungkin antar modulnya, dan memiliki cohesion yang dibuat setinggi mungkin di dalam modulnya. Untuk review, silakan baca link ini.
Feature Envy
sourcemaking | refactoring.guru | before | after
Penjelasan Smell
Setiap harinya, Yasugi selalu mengunjungi rumah Kabuto yang berada di sebelahnya karena sepeda motor yang dia miliki ia parkirkan di rumah tersebut. Namun pada kenyataannya, Yasugi juga sering mengintip adik Kabuto main PS4 karena dia senang main bola. Eh digampar si Yasugi! Ya siapa suruh ngintip-ngintip adek mereka main game?
Smell ini terjadi bila ada sebuah method yang lebih sering mengakses data class lain ketimbang class sendiri. Class sendiri pun menjadi ‘cemburu’. Bila hal ini terjadi, harus dipikirkan bagaimana cara mengusir method ini ke class lain tersebut.
Pada contoh Lecturer.java, terdapat method isScored
yang hanya mengakses data examiner di class Exam.
public boolean isScored(Exam exam) {
return exam.getExaminer() != null;
}
Penyelesaian
Dilakukan Move Method pada fungsi isScored
. Perhatikan di package after
, isScored dipindahkan ke class Exam.
Selain itu, code fragment ini pun dipindahkan juga ke fungsi setScore
di class Exam.
if(this.isScored()) {
throw new IllegalArgumentException("exam already scored");
}
Tambahan
Di bukunya, Martin Fowler menyatakan bahwa ada beberapa kondisi class atau method yang sengaja dirancang untuk hanya consume data di class lain. Contoh yang paling umum terjadi adalah penggunaan design pattern Strategy atau Visitor. Design pattern ini masuk ke dalam Gang of Four Design Pattern, akan kita pelajari di semester depan.
Inappropriate Intimacy
sourcemaking | refactoring.guru | before | after
Penjelasan Smell
Ceritanya ada grup chat yang terdiri dari 7 orang. Ketujuh orang ini memiliki dustanya masing-masing mulai dari maling sendal, SMS mama minta duit, anak tawuran, hingga koleksi wikwik. Namun gara-gara programmer mengekspos profile user, eh kebongkar dusta-dustanya mereka ber-tujuh!
Smell ini terjadi karena hubungan antar class yang terlalu intim, menyebabkan class yang satu mengeksploitasi internal field dan/atau method di class lain.
Hal ini berbahaya karena class yang internal logic-nya diakses bisa mendapat perlakuan yang tidak terduga.
Pada constructor di Product.java, class Product mengetahui ada fungsi addTag
di Catalog dan menambahkan tag-nya sendiri ke Catalog.
public Product(String name, double price, Catalog catalog) {
...
this.catalog.addTag(this, Catalog.NEWCOMER_TAG);
}
Hal ini tentu berbahaya karena artinya, class Product bisa menambahkan tag apapun tanpa seizin Catalog.
Penyelesaian
Catalog dan Product punya hubungan bidirectional yang tidak perlu, maka dilakukan Change Bidirectional Association to Unidirectional. Dengan cara menghapus field catalog
di dalam Product
.
Semua method di class Catalog yang berhubungan dengan manipulasi tag access modifier-nya diubah menjadi private.
Message Chains
sourcemaking | refactoring.guru | before | after
Penjelasan Smell
Pada zaman dulu sebelum adanya pos Merpati, manusia mengandalkan teriakan untuk mengirimkan informasi kepada orang yang diinginkan. Eh tapi kan zaman dulu! Kenapa tidak pakai internet aja? Kan lebih cepat dan efisien.
Smell ini terjadi ketika ingin mengakses sebuah method, perlu dilakukan pemanggilan dari hasil return method lainnya sehingga membentuk rantai: obj.a().b().c()
.
Perhatikan DistanceTest.java, terdapat message chaining ketika ingin mengakses latitude dan longitude.
...
driver.getCurrentPosition().getLatitude();
...
Penyelesaian
Dilakukan Hide Delegate. Perhatikan class BojekDriver dan Destination, telah ditambahkan fungsi latitude()
dan longitude()
yang sebenarnya melakukan delegasi chaining yang dilakukan di package before. Hal ini dilakukan agar class client tidak merasakan adanya chaining, disembunyikan di dalam sini.
public double latitude() {
return this.getCurrentPosition().getLatitude();
}
public double longitude() {
return this.getCurrentPosition().getLongitude();
}
Alhasil, seperti yang bisa dilihat di DistanceTest.java di package after, message chain sudah tidak ada.
Tambahan
Jangan terlalu agresif mengurusi message chain karena bisa menyebabkan smell Middle Man.
Pertimbangkan mengurusi message chain bila terjadi di banyak tempat atau kebetulan ada class yang behavior-nya cocok untuk menampung method delegasi.
Middle Man
sourcemaking | refactoring.guru | before | after
Penjelasan Smell
Pada beberapa kasus, para lelaki harus membayarkan tip kepada ‘preman’ sebelum mereka bisa bertemu dengan wanita yang mereka inginkan. Lah kan adik aku, kenapa aku malah dipalak juga? Kan kita cuma beda jenis kelamin mengapa kita kena palak?
Middle Man adalah class yang isinya hanya delegasi saja, tidak ada behavior lain selain delegasi ke class lain.
Perhatikan LinkedList.java dan ShoppingCart.java. ShoppingCart
melakukan add
pada LinkedList
. Namun ternyata di dalam LinkedList
, dia hanya delegasi ke java.util.Vector
.
Penyelesaian
Hapus si Middle Man, yaitu LinkedList
. Sekarang di package after, class ShoppingCart
langsung mengakses java.util.Vector
.
Tambahan
Ada beberapa design pattern yang memang dirancang untuk delegasi, seperti: Adapter, Proxy, Bridge, Facade atau Mediator. Namun dalam design pattern ini bukan sekadar delegasi mentah-mentah, ada sedikit fitur di dalamnya. Design pattern ini masuk ke dalam Gang of Four Design Pattern, akan kita pelajari di semester depan.
Referensi Gambar
Semua gambar referensi mengikuti pictorial gambar pada Refactoring.guru dengan tetap mengutamakan link credit pada sourcemaking.com maupun refactoring.guru