Ini adalah topik yang agak kontroversial, dan saya kira ada banyak pendapat karena ada programmer. Tetapi demi itu, saya ingin tahu apa praktik umum dalam bisnis (atau di tempat kerja Anda).
Di tempat kerja saya, kami memiliki pedoman pengkodean yang ketat. Satu bagian dari itu didedikasikan untuk string / angka ajaib. Ini menyatakan (untuk C #):
Jangan gunakan nilai literal, baik numerik atau string, dalam kode Anda selain untuk mendefinisikan konstanta simbolik. Gunakan pola berikut untuk mendefinisikan konstanta:
public class Whatever { public static readonly Color PapayaWhip = new Color(0xFFEFD5); public const int MaxNumberOfWheels = 18; }
Ada pengecualian: nilai 0, 1 dan nol hampir selalu dapat digunakan dengan aman. Sangat sering nilai 2 dan -1 juga OK. String yang dimaksudkan untuk logging atau tracing dikecualikan dari aturan ini. Literal diizinkan ketika maknanya jelas dari konteksnya, dan tidak tunduk pada perubahan di masa depan.
mean = (a + b) / 2; // okay
WaitMilliseconds(waitTimeInSeconds * 1000); // clear enough
Situasi yang ideal adalah beberapa makalah penelitian resmi yang menunjukkan efek pada keterbacaan / pemeliharaan kode ketika:
- Angka ajaib / senar ada di semua tempat
- String / angka ajaib digantikan oleh deklarasi konstan secara wajar (atau dalam berbagai tingkat cakupan) - dan tolong jangan meneriaki saya karena menggunakan "cukup", saya tahu semua orang memiliki ide yang berbeda apa "cukup" itu
- String / angka ajaib ditempatkan secara berlebihan dan di tempat-tempat di mana mereka tidak harus (lihat contoh saya di bawah)
Saya ingin melakukan ini untuk memiliki beberapa argumen berbasis ilmiah ketika berdebat dengan salah satu kolega saya, yang akan sampai pada titik menyatakan konstanta seperti:
private const char SemiColon = ';';
private const char Space = ' ';
private const int NumberTen = 10;
Contoh lain adalah (dan ini dalam JavaScript):
var someNumericDisplay = new NumericDisplay("#Div_ID_Here");
Apakah Anda menempelkan DOM ID di atas file javascript Anda jika ID itu hanya digunakan di 1 tempat?
Saya telah membaca topik-topik berikut:
StackExchange
StackOverflow
Bytes Komunitas TI
Ada banyak lagi artikel, dan setelah membaca beberapa pola ini muncul.
Jadi pertanyaan saya adalah harus menggunakan string dan angka ajaib dalam kode kita? Saya secara khusus mencari jawaban ahli yang didukung oleh referensi jika memungkinkan.
sumber
NumberTen = 10
Itu tidak ada gunanya karena angka 10 tidak akan didefinisikan ulang.MaxRetryCount = 10
Itu ada titik a kita mungkin ingin mengubah jumlah coba lagi maks.private const char SemiColon = ';';
Bodoh.private const char LineTerminator = ';'
; Pintar.Jawaban:
Argumen yang perlu Anda ajukan dengan kolega Anda bukan tentang penamaan ruang literal
Space
melainkan pilihan nama yang buruk untuk konstanta-konstanta.Katakanlah tugas kode Anda adalah mengurai aliran catatan yang berisi bidang yang dipisahkan oleh tanda titik koma (
a;b;c
) dan dipisahkan oleh spasi (a;b;c d;e;f
). Jika siapa pun yang menulis spec Anda memanggil Anda sebulan dari sekarang dan berkata, "kami salah, bidang dalam catatan dipisahkan oleh simbol pipa (a|b|c d|e|f
)," apa yang Anda lakukan?Di bawah skema nilai-sebagai-nama yang disukai kolega Anda, Anda harus mengubah nilai literal (
SemiColon = '|'
) dan hidup dengan kode yang terus digunakanSemiColon
untuk sesuatu yang tidak benar-benar titik koma lagi. Itu akan menghasilkan komentar negatif dalam ulasan kode . Untuk menguranginya, Anda dapat mengubah nama literal menjadiPipeSymbol
dan melewati dan mengubah setiap kemunculanSemiColon
kePipeSymbol
. Pada tingkat itu Anda mungkin baru saja menggunakan titik koma literal (';'
), karena Anda harus mengevaluasi setiap penggunaannya secara individual dan Anda akan membuat jumlah perubahan yang sama.Pengidentifikasi untuk konstanta harus deskriptif apa nilai tidak , tidak apa nilai adalah , dan bahwa di mana rekan Anda telah membuat berbelok ke kiri ke dalam gulma. Dalam aplikasi pemisahan lapangan yang dijelaskan di atas, tujuan titik koma adalah pemisah medan, dan konstanta harus dinamai sesuai:
Dengan cara ini, ketika pemisah bidang berubah, Anda mengubah tepat satu baris kode, pernyataan konstanta. Seseorang yang melihat perubahan akan melihat hanya satu baris itu dan akan segera memahami bahwa pemisah bidang berubah dari tanda titik koma menjadi simbol pipa. Sisa kode, yang tidak perlu diubah karena menggunakan konstanta, tetap sama, dan pembaca tidak perlu menggali untuk melihat apa yang dilakukan untuk itu.
sumber
#define one 1 #define two 2
dll (atau apa pun yang sederajat itu di UK Post Office Coral, bahasa pilihan saat itu). Kata datang dari atas bahwa di masa depan bidang panjang akan menjadi jumlah byte, bukan segmen, jadi jelas kode itu diubah menjadi#define one 8 #define two 16
dll;
untuk|
.public static final String MY_KEY_NAME = "MyKeyName"
CSV_RECORD_SEPARATOR
,TSV_RECORD_SEPARATOR
, dll).Mendefinisikan titik koma sebagai konstanta adalah mubazir, karena titik koma sudah konstan dengan sendirinya . Itu tidak akan pernah berubah.
Ini tidak seperti suatu hari seseorang akan mengumumkan "perubahan terminologi, + adalah titik koma baru sekarang", dan kolega Anda akan dengan senang hati bergegas hanya untuk memperbarui konstanta (mereka menertawakan saya - lihat mereka sekarang).
Ada juga masalah konsistensi. Saya menjamin bahwa
NumberTen
konstanta nya TIDAK akan digunakan oleh semua orang (kebanyakan coders tidak keluar dari pikiran mereka), jadi itu tidak akan melayani tujuan apa pun yang diharapkan pula. Ketika kiamat datang dan "sepuluh" akan secara global diubah menjadi 9, memperbarui konstanta TIDAK akan melakukan trik, karena itu masih akan meninggalkan Anda dengan tumpukan literal10
dalam kode Anda, jadi sekarang sistem menjadi benar-benar tidak dapat diprediksi bahkan dalam ruang lingkup dari asumsi revolusioner bahwa "sepuluh" berarti "9".Menyimpan semua pengaturan sebagai const adalah sesuatu yang saya juga pikirkan. Seseorang seharusnya tidak melakukan ini dengan enteng.
Apa contoh penggunaan seperti ini yang telah kami kumpulkan sejauh ini? Terminator garis ... jumlah coba lagi maks ... jumlah roda maksimum ... apakah kami yakin ini tidak akan pernah berubah?
Biayanya adalah bahwa mengubah pengaturan default memerlukan kompilasi ulang aplikasi, dan dalam beberapa kasus, bahkan dependensinya (karena nilai konstanta numerik mungkin mendapatkan kode-keras selama kompilasi).
Ada juga aspek pengujian dan mengejek. Anda mendefinisikan string koneksi sebagai const, tetapi sekarang oops Anda tidak dapat mengejek akses database (membuat koneksi palsu) di unit test Anda.
sumber
’
(kutipan tunggal, Unicode 8217 ) untuk aplikasi yang kompatibel dengan menampilkan mesin terbang yang berbeda untuk tanda keriting. Menjadi bahwa Eropa menggunakan koma cara Amerika menggunakan titik sebagai titik desimal, saya menemukan diri saya sedikit ragu untuk menyatakan "tidak ... pernah".DecimalPoint
konstanta - tetapi tidakComma
atauPeriod
konstanta. Perbedaannya cukup besar: yang pertama menunjukkan fungsi , peran atau tujuan dari nilai. "Titik koma" atau "koma" tidak termasuk dalam kategori itu.Jadi kolega Anda membidik entri WTF Harian. Definisi-definisi itu konyol dan berlebihan. Namun, seperti yang telah ditunjukkan oleh orang lain, definisi berikut tidak akan konyol atau berlebihan:
Angka dan senar "ajaib" adalah konstanta yang memiliki makna di luar nilai langsung dan harfiahnya. Jika konstanta
10
memiliki makna di luar "sepuluh hal" (katakanlah sebagai kode untuk operasi atau kondisi kesalahan tertentu), saat itulah ia menjadi "ajaib" dan harus diganti dengan konstanta simbolik yang menggambarkan makna abstrak itu.Di luar jelas menggambarkan niat, konstanta simbolis juga menyelamatkan Anda dari sakit kepala ketika Anda salah mengeja literal. Transposisi sederhana dari "CVS" ke "CSV" dalam satu baris kode berhasil melalui pengujian unit dan QA dan membuatnya menjadi produksi, di mana ia menyebabkan operasi tertentu gagal. Ya, jelas unit dan tes QA tidak lengkap dan itu masalah sendiri, tetapi menggunakan konstanta simbolis akan menghindari sedikit mulas itu sama sekali.
sumber
Seharusnya tidak ada yang kontroversial tentang hal itu. Intinya bukan tentang apakah menggunakan angka ajaib atau tidak, intinya adalah memiliki kode yang dapat dibaca.
Pertimbangkan perbedaan antara:
if(request.StatusCode == 1)
danif(request.HasSucceeded)
. Dalam hal ini, saya berpendapat bahwa yang terakhir jauh lebih mudah dibaca, tetapi itu tidak berarti Anda tidak akan pernah memiliki kode sepertiint MaxNumberOfWheels = 18
.PS: Inilah sebabnya saya sangat membenci pedoman pengkodean. Pengembang harus cukup dewasa untuk dapat membuat penilaian seperti ini; mereka tidak harus menyerahkannya pada selembar teks yang dibentuk oleh dewa yang tahu siapa.
sumber