Ada beberapa masalah dengan kode ini, yang, dapat, disingkat menjadi seperti ini:
public List<Money> getMoneyByPersons() {
return persons.size() == 1 ?
moneyService.getMoneyIfHasOnePerson() :
moneyService.getMoney();
}
Tidak jelas mengapa satu orang adalah kasus khusus. Saya kira ada aturan bisnis tertentu yang mengatakan bahwa mendapatkan uang dari satu orang secara radikal berbeda dari mendapatkan uang dari beberapa orang. Namun, saya harus pergi dan melihat ke dalam keduanya getMoneyIfHasOnePerson
dan getMoney
, berharap untuk memahami mengapa ada kasus yang berbeda.
Nama getMoneyIfHasOnePerson
itu kelihatannya tidak benar. Dari namanya, saya akan mengharapkan metode untuk memeriksa apakah ada satu orang dan, jika ini masalahnya, dapatkan uang darinya; jika tidak, jangan lakukan apa pun. Dari kode Anda, ini bukan yang terjadi (atau Anda melakukan kondisinya dua kali).
Apakah ada alasan untuk mengembalikan List<Money>
koleksi daripada koleksi?
Kembali ke pertanyaan Anda, karena tidak jelas mengapa ada perlakuan khusus untuk satu orang, digit yang satu harus diganti dengan konstanta, kecuali ada cara lain untuk membuat aturan eksplisit. Di sini, satu tidak jauh berbeda dari angka ajaib lainnya. Anda dapat memiliki aturan bisnis yang mengatakan bahwa perlakuan khusus berlaku untuk satu, dua atau tiga orang, atau hanya untuk lebih dari dua belas orang.
Bagaimana saya membedakan konteks untuk memilih solusi terbaik?
Anda melakukan apa pun yang membuat kode Anda lebih eksplisit.
Contoh 1
Bayangkan potongan kode berikut:
if (sequence.size() == 0) {
return null;
}
return this.processSequence(sequence);
Apakah nol di sini nilai magis? Kode agak jelas: jika tidak ada elemen dalam urutan, jangan diproses dan mengembalikan nilai khusus. Tetapi kode ini juga dapat ditulis ulang seperti ini:
if (sequence.isEmpty()) {
return null;
}
return this.processSequence(sequence);
Di sini, tidak ada lagi yang konstan, dan kodenya bahkan lebih jelas.
Contoh 2
Ambil satu lagi kode:
const result = Math.round(input * 1000) / 1000;
Tidak perlu terlalu banyak waktu untuk memahami apa yang dilakukannya dalam bahasa seperti JavaScript yang tidak memiliki round(value, precision)
kelebihan.
Sekarang, jika Anda ingin memperkenalkan sebuah konstanta, bagaimana ini akan disebut? Istilah terdekat yang bisa Anda dapatkan adalah Precision
. Begitu:
const precision = 1000;
const result = Math.round(input * precision) / precision;
Apakah ini meningkatkan keterbacaan? Mungkin. Di sini, nilai konstanta agak terbatas, dan Anda mungkin bertanya pada diri sendiri apakah Anda benar-benar perlu melakukan refactoring. Yang menyenangkan di sini adalah bahwa sekarang, ketepatannya dinyatakan hanya sekali, jadi jika itu berubah, Anda tidak mengambil risiko membuat kesalahan seperti:
const result = Math.round(input * 100) / 1000;
mengubah nilai di satu lokasi, dan lupa melakukannya di yang lain.
Contoh 3
Dari contoh-contoh itu, Anda mungkin memiliki kesan bahwa angka harus diganti dengan konstanta dalam setiap kasus . Ini tidak benar. Dalam beberapa situasi, memiliki konstanta tidak mengarah pada peningkatan kode.
Ambil bagian kode berikut:
class Point
{
...
public void Reset()
{
x, y = (0, 0);
}
}
Jika Anda mencoba mengganti nol dengan variabel, kesulitannya adalah menemukan nama yang bermakna. Bagaimana Anda menyebutkannya? ZeroPosition
? Base
? Default
? Memperkenalkan konstanta di sini tidak akan meningkatkan kode dengan cara apa pun. Itu akan membuatnya sedikit lebih lama, dan hanya itu.
Namun kasus seperti itu jarang terjadi. Jadi, setiap kali Anda menemukan angka dalam kode, berusahalah untuk menemukan bagaimana kode tersebut dapat di-refactored. Tanyakan pada diri Anda apakah ada bisnis yang berarti nomor tersebut. Jika ya, konstanta adalah wajib. Jika tidak, bagaimana Anda menyebutkan nomornya? Jika Anda menemukan nama yang bermakna, itu bagus. Jika tidak, kemungkinan Anda menemukan kasus di mana konstanta tidak diperlukan.
persons
dan apa yang digambarkannya? Kode Anda tidak memiliki komentar apa pun sehingga sulit untuk menebak apa yang dilakukannya.