Feature Envy
Feature Envy adalah sebuah code smell yang di mana sebuah kelas atau modul
menggunakan metode atau data dari kelas lain secara berlebihan, menunjukkan bahwa
kelas yang bergantung mungkin mencoba melakukan terlalu banyak hal atau bahwa desainnya
mungkin kurang terstruktur. Dengan kata lain, jika sebuah kelas atau modul menggunakan
data atau metode dari kelas lain lebih dari miliknya sendiri, itu mungkin merupakan tanda
bahwa kelas yang bergantung "cemburu" terhadap fitur dari kelas lain tersebut.
Hal ini dapat menyebabkan keterikatan yang erat antara kelas-kelas tersebut,
yang dapat membuat kode menjadi sulit untuk dipelihara dan dipahami.
Perawatan
Jika ada perubahan pada data dan fungsi yang terkait pada saat yang sama, biasanya disarankan
untuk menyimpannya di tempat yang sama. Data dan fungsi yang berkaitan cenderung diubah bersamaan
(meskipun ada pengecualian).
- Jika sebuah metode jelas seharusnya dipindahkan ke tempat lain, gunakanlah Move Method.
- Jika hanya sebagian dari sebuah metode yang mengakses data dari objek lain, gunakan Extract Method
untuk memindahkan bagian tersebut.
- Jika sebuah metode menggunakan fungsi dari beberapa kelas lain, pertama-tama tentukan kelas mana yang
mengandung sebagian besar data yang digunakan. Kemudian tempatkan metode ini di dalam kelas tersebut bersama
dengan data yang lain. Sebagai alternatif, gunakan "Extract Method" untuk membagi metode menjadi beberapa
bagian yang dapat ditempatkan di berbagai tempat di berbagai kelas yang berbeda.
Keuntungan
- Reduksi Duplikasi Kode : Dengan menempatkan kode penanganan data di satu tempat pusat, Anda dapat
mengurangi duplikasi kode. Ini mengurangi kemungkinan adanya beberapa versi dari kode yang sama yang tersebar di
berbagai bagian proyek
- Organisasi Kode yang Lebih Baik : Metode untuk menangani data akan berada di dekat data aktual,
yang membuat struktur kode lebih terorganisir. Hal ini memudahkan untuk memahami hubungan antara data dan metode
yang mengoperasikannya, sehingga meningkatkan keterbacaan dan pemeliharaan kode.
Kapan Untuk Diabaibaikan
Kadang-kadang perilaku sengaja dipisahkan dari kelas yang menyimpan data. Keuntungan biasanya dari ini adalah
kemampuan untuk secara dinamis mengubah perilaku
Contoh
Masalah
public class Phone {
private final String unformattedNumber;
public Phone(String unformattedNumber) {
this.unformattedNumber = unformattedNumber;
}
public String getAreaCode() {
return unformattedNumber.substring(0,3);
}
public String getPrefix() {
return unformattedNumber.substring(3,6);
}
public String getNumber() {
return unformattedNumber.substring(6,10);
}
}
public class Customer {
private Phone mobilePhone;
public String getMobilePhoneNumber() {
return "(" +
mobilePhone.getAreaCode() + ") " +
mobilePhone.getPrefix() + "-" +
mobilePhone.getNumber();
}
}
Solusi
public class Phone {
private final String unformattedNumber;
public Phone(String unformattedNumber) {
this.unformattedNumber = unformattedNumber;
}
public String getAreaCode() {
return unformattedNumber.substring(0,3);
}
public String getPrefix() {
return unformattedNumber.substring(3,6);
}
public String getNumber() {
return unformattedNumber.substring(6,10);
}
public String getFormattedNumber() {
return "(" + getAreaCode() + ") " + getPrefix() + "-" + getNumber();
}
}
public class Customer {
private Phone mobilePhone;
public String getMobilePhoneNumber() {
return mobilePhone.getFormattedNumber();
}
}
Dalam contoh ini, kelas Customer
menggunakan metode kelas Phone secara berlebihan,
yang merupakan tanda "Feature Envy". Ini dapat menyebabkan tingkat keterikatan yang
tinggi antara kedua kelas tersebut dan duplikasi kode yang tidak perlu.
Untuk mengatasi masalah kode ini, salah satu solusinya adalah memindahkan metode
getMobilePhoneNumber
ke kelas Phone
dan memodifikasinya
agar mengembalikan nomor telepon yang diformat secara langsung. Kita memindahkan metode getFormattedNumber
dari kelas
Customer
ke kelas Phone
. Dengan cara ini, kelas Phone
bertanggung jawab untuk
memformat nomor teleponnya sendiri, yang mengatasi masalah "Feature Envy" dalam kode. Kelas
Customer sekarang hanya memanggil metode getFormattedNumber pada objek Phone untuk
mendapatkan nomor telepon yang diformat.