Saya telah melakukan sedikit perdebatan dengan rekan kerja belakangan ini. Kami secara khusus menggunakan C #, tetapi ini bisa berlaku untuk bahasa apa pun dengan tipe nullable. Katakan misalnya Anda memiliki nilai yang mewakili maksimum. Namun, nilai maksimum ini bersifat opsional. Saya berpendapat bahwa angka yang dapat dibatalkan lebih disukai. Rekan kerja saya lebih suka menggunakan nol, dengan mengutip preseden. Memang, hal-hal seperti soket jaringan sering menggunakan nol untuk mewakili batas waktu tanpa batas. Jika saya menulis kode yang berhubungan dengan soket hari ini, saya pribadi akan menggunakan nilai nullable, karena saya merasa akan lebih baik mewakili kenyataan bahwa tidak ada batas waktu.
Representasi mana yang lebih baik? Keduanya memerlukan kondisi yang memeriksa nilai yang berarti "tidak ada", tapi saya percaya bahwa tipe nullable menyampaikan maksud sedikit lebih baik.
sumber
Jawaban:
Mempertimbangkan:
Bahasa,
Kerangka,
Konteks.
1. Bahasa
Menggunakan ∞ bisa menjadi solusi maksimal.
JavaScript, misalnya, memiliki jumlah tak terbatas. C # tidak¹.
Ada, misalnya, memiliki rentang. C # tidak.
Di C #, ada
int.MaxValue
, tetapi Anda tidak dapat menggunakannya dalam kasing Anda.int.MaxValue
adalah bilangan bulat maksimum, 2.147.483.647. Jika dalam kode Anda, Anda memiliki nilai maksimum sesuatu, seperti tekanan maksimum yang diterima sebelum sesuatu meledak, menggunakan 2.147.483.647 tidak masuk akal.2. Kerangka Kerja
.NET Framework agak tidak konsisten dalam hal ini, dan penggunaan nilai-nilai ajaibnya dapat dikritik.
Misalnya,
"Hello".IndexOf("Z")
mengembalikan nilai ajaib-1
. Ini mungkin membuat lebih mudah (bukan?) Untuk memanipulasi hasilnya:daripada menggunakan struktur khusus:
tetapi tidak intuitif sama sekali. Kenapa
-1
dan tidak-123
? Seorang pemula juga mungkin secara keliru berpikir bahwa itu0
berarti "Tidak ditemukan" juga atau salah ketik(position >= 0)
.3. Konteks
Jika kode Anda terkait dengan timeout di soket jaringan, menggunakan sesuatu yang telah digunakan oleh semua orang selama beberapa dekade demi menjadi konsisten bukanlah ide yang buruk . Terutama,
0
untuk batas waktu sangat jelas: ini adalah nilai yang tidak boleh nol. Menggunakan kelas khusus dalam hal ini dapat membuat hal-hal lebih sulit untuk dipahami:Duration
ke 0 jikaIsTimeoutEnabled
itu benar?IsTimeoutEnabled
salah, apa yang terjadi jika saya menetapkanDuration
ke 100?Ini dapat menyebabkan banyak kesalahan. Bayangkan potongan kode berikut:
Operasi berjalan selama sepuluh detik. Bisakah Anda melihat apa yang salah dengan kode ini, tanpa membaca dokumentasi
Timeout
kelas?Kesimpulan
null
mengungkapkan dengan baik gagasan bahwa nilainya tidak ada di sini. Itu tidak disediakan. Tidak tersedia. Ini bukan angka, atau string nol / kosong atau apa pun. Jangan gunakan untuk nilai maksimum atau minimum.int.MaxValue
sangat terkait dengan bahasa itu sendiri. Jangan gunakanint.MaxValue
untuk batas kecepatan maksimumVehicle
kelas atau kecepatan maksimum yang dapat diterima untuk pesawat terbang, dll.Hindari nilai-nilai ajaib seperti
-1
dalam kode Anda. Mereka menyesatkan dan menyebabkan kesalahan dalam kode.Buat kelas Anda sendiri yang akan lebih mudah, dengan nilai minimum / maksimum yang ditentukan. Misalnya
VehicleSpeed
bisa punyaVehicleSpeed.MaxValue
.Jangan ikuti panduan sebelumnya dan gunakan nilai sihir jika itu adalah konvensi umum selama beberapa dekade dalam bidang yang sangat spesifik, yang digunakan oleh kebanyakan orang menulis kode di bidang ini.
Jangan lupa untuk menggabungkan pendekatan. Sebagai contoh:
¹ Anda dapat membuat tipe Anda sendiri yang mencakup infinity. Di sini, saya berbicara tentang
int
tipe asli saja.sumber
int
tidak cukup mengungkapkan tentang jenis untuk membatasi masalah, pertimbangkan struct baru dengan info lebih lanjut (contoh konst dari struct yang mewakili nilai-nilai sihir, misalnya, atau enum untuk mengindikasikan). Atau pertimbangkan pemrograman kontrak atau beberapa solusi lain, tapi saya pikir struct kustom paling mudah.Null tidak lebih baik dari angka ajaib.
Yang penting adalah untuk NAMA nilai-nilai yang memiliki efek sihir, jika Anda harus memiliki nilai-nilai seperti itu, dan untuk memastikan bahwa definisi nama-nama itu adalah suatu tempat yang akan dilihat oleh siapa saja yang menabrak nilai sihir dan wtf.
sumber
MAGIC_NUMBER
kode harus benar-benar selalu dihindari sedapat mungkin.null
adalah ungkapan niat yang jauh lebih jelas.sumber
Dalam C #, banyak kelas CLR memiliki anggota statis
Empty
:System.String.Empty
System.EventArgs.Empty
System.Guid.Empty
System.Drawing.Rectangle.Empty
System.Windows.Size.Empty
Ini membuat Anda tidak perlu mengingat apakah akan menggunakan nilai ajaib atau menggunakan null untuk membangun objek kosong.
Tetapi bagaimana jika Anda berurusan dengan tipe nilai sederhana seperti
int
? Dalam hal itu, pertimbangkan apakah Anda menjadi korban Obsesi Primitif . Sangat mungkin bahwa properti numerik Anda yang tampaknya sederhana akan mendapat manfaat dari kelas atau struct sendiri, yang akan memungkinkan Anda untuk menentukanEmpty
anggota dan juga menambahkan perilaku lain yang spesifik untuk nilai semacam itu.sumber
Dalam hal ini, nilai nol adalah cara yang bagus untuk menunjukkan tidak ada maksimum. Secara umum ketika kasus khusus berarti bahwa nilai yang dipermasalahkan tidak berlaku, bahwa Anda tidak ingin fitur yang dikonfigurasikan, null adalah indikasi yang baik untuk ini.
Masalah dengan menggunakan null untuk mewakili kasus khusus adalah bahwa hanya ada satu nilai nol, dan mungkin ada beberapa kasus khusus. Dalam hal ini, saya akan meneruskan enumerasi sebagai parameter tambahan, yang dapat menunjukkan kasus khusus, atau menggunakan nilai int secara normal. (Ini pada dasarnya apa yang Nullable <> lakukan untuk Anda, meskipun ia menggunakan boolean bukan enum dan menggabungkan parameter ke dalam satu struktur.)
sumber
Dalam hal ini, saya pikir tipe nullable masuk akal.
Null berarti tidak adanya nilai. Ini adalah konsep yang sangat berbeda dari angka yang memiliki nilai 0.
Jika Anda ingin mengatakan "Jika saya tidak memberi Anda nilai, gunakan nilai maksimum" lalu memasukkan nol adalah cara yang tepat untuk mengekspresikannya.
sumber
Null: nilai kesalahan umum, tidak ditentukan, tidak berlaku, atau tidak ada nilai.
Nol: Nilai aktual, tetapi tidak selalu logis atau intuitif (dalam konteks ini). Juga merupakan nilai umum dalam inisialisasi.
Dalam konteks masalah Anda,
timeoutInMilliseconds
properti bersifat opsional dan tidak disebutkan bahwa overhead pendekatan ini akan mendiskualifikasi sebagai opsi.Kesimpulan: Ada pengecualian, dan solusi bervariasi berdasarkan bahasa dan domain; dalam hal ini, saya akan memilih Null. Di mana (saya percaya) beberapa orang melakukan kesalahan ini adalah ketika mereka tidak memisahkan data dari antarmuka dengan baik. Mereka hanya mengharapkan klien untuk membaca dokumentasi (atau implementasi) untuk menentukan bagaimana nilai-nilai khusus ini akan digunakan / ditangani - kasus-kasus khusus bocor ke dalam program klien dan itu bisa sangat tidak jelas. Dengan menambahkan lapisan abstraksi yang baik, penggunaannya bisa jauh lebih jelas.
sumber
Null lebih buruk untuk digunakan daripada
MagicNumber
. Null mewakili ide yang diekspresikan lebih baik, tetapi tidak konsisten di seluruh platform dalam bagaimana berperilaku, menggunakanMagicNumber
selalu bekerja sama yang bermanfaat.tergantung pada lingkungan / bahasa yang digunakan null bisa
MagicNumber
selalu berperilaku sama.sumber
Jika Anda lupa untuk memeriksa nomor ajaib (yang akan terjadi dengan benar), maka nomor ajaib akan berlanjut sebentar dengan data yang tidak masuk akal. Jauh lebih baik memiliki null yang menyebabkan pengecualian sesegera mungkin.
sumber
Null bukan satu-satunya alternatif untuk angka ajaib.
Null itu jahat. Dalam contoh di atas, Anda mungkin bisa lolos karena kode jelas akan dapat menangani nol. Tetapi secara umum apa yang terjadi ketika Anda mulai melewati nol adalah bahwa cepat atau lambat Anda mendapatkan pengecualian penunjuk nol. Ini mungkin tidak terjadi ketika Anda pertama kali menulis kode, tetapi kode dipertahankan lebih lama dari rilis pertama. Ini sering dikelola oleh orang-orang yang tidak tahu banyak tentang sistem seperti pengembang asli.
Scala (misalnya) memiliki alternatif yang bagus di kelas Opsi. Kelas Opsi memiliki satu dari dua nilai, Beberapa - yang membungkus nilai yang Anda inginkan dan Tidak Ada - yang tidak memiliki nilai.
Itu membuat jelas bagi pengembang mana pun bahwa mungkin tidak ada nilai dan Anda memiliki kode yang lebih baik untuk itu. Yah, bagaimanapun juga harus jelas.
Dan tidak semua angka ajaib adalah masalah. Tergantung pada konteks 0, 1, 1024 dll semuanya bisa jelas. 347? Ya, yang harus Anda hindari. :-)
sumber