Saya membuat model objek untuk perangkat yang memiliki banyak saluran. Kata benda yang digunakan antara klien dan saya adalah Channel
dan ChannelSet
. ("Set" tidak akurat secara semantik, karena itu diatur dan set yang tepat tidak. Tapi itu masalah untuk waktu yang berbeda.)
Saya menggunakan C #. Berikut adalah contoh penggunaan ChannelSet
:
// load a 5-channel ChannelSet
ChannelSet channels = ChannelSetFactory.FromFile("some_5_channel_set.json");
Console.Write(channels.Count);
// -> 5
foreach (Channel channel in channels) {
Console.Write(channel.Average);
Console.Write(", ");
}
// -> 0.3, 0.3, 0.9, 0.1, 0.2
Semuanya keren. Namun, klien bukan pemrogram dan mereka benar - benar akan bingung dengan pengindeksan nol - saluran pertama adalah saluran 1 untuk mereka. Tapi, demi konsistensi dengan C #, saya ingin menjaga ChannelSet
indeks dari nol .
Ini pasti akan menyebabkan beberapa terputusnya antara tim dev saya dan klien ketika mereka berinteraksi. Tetapi lebih buruk lagi, setiap inkonsistensi dalam bagaimana hal ini ditangani dalam basis kode adalah masalah potensial. Misalnya, inilah layar UI tempat pengguna akhir ( yang berpikir dalam 1 indeks ) mengedit saluran 13:
Itu Save
tombol pada akhirnya akan menghasilkan beberapa kode. Jika ChannelSet
1 diindeks:
channels.GetChannel(13).SomeProperty = newValue; // notice: 13
atau ini jika nol diindeks:
channels.GetChannel(12).SomeProperty = newValue; // notice: 12
Saya tidak begitu yakin bagaimana menangani ini. Saya merasa ini adalah praktik yang baik untuk menjaga daftar hal-hal yang teratur (integer-indexed) dari hal-hal (yang ChannelSet
) konsisten dengan semua array dan daftar antarmuka lainnya di alam semesta C # (dengan pengindeksan nol ChannelSet
). Tapi kemudian setiap bagian kode antara UI dan backend akan membutuhkan terjemahan (kurangi dengan 1), dan kita semua tahu betapa berbahaya dan umum kesalahan yang sudah ada.
Jadi, pernahkah keputusan seperti ini menggigit Anda? Haruskah saya nol indeks atau satu indeks?
sumber
Jawaban:
Rasanya seperti Anda sedang menyatukan Identifier
Channel
dengan posisinya dalam aChannelSet
. Berikut ini adalah visualisasi saya tentang bagaimana kode / komentar Anda akan terlihat saat ini:Rasanya seperti Anda telah memutuskan bahwa karena
Channel
s di dalamChannelSet
diidentifikasi dengan angka yang memiliki batas atas dan bawah mereka harus indeks dan oleh karena itu berdasarkan C #, 0. Jika cara alami untuk merujuk ke masing-masing saluran adalah dengan angka antara 1 dan X, rujuklah dengan angka antara 1 dan X. Jangan mencoba dan memaksa mereka menjadi indeks.Jika Anda benar-benar ingin memberikan cara untuk mengaksesnya dengan indeks berbasis 0 (manfaat apa yang diberikan pengguna akhir Anda, atau pengembang yang menggunakan kode?) Kemudian mengimplementasikan Indexer :
sumber
Tampilkan UI dengan indeks 1, gunakan indeks 0 dalam kode.
Yang mengatakan, saya bekerja dengan perangkat audio seperti ini dan menggunakan indeks 1 untuk saluran dan merancang kode untuk tidak pernah menggunakan "Indeks" atau pengindeks untuk membantu menghindari frustrasi. Beberapa programmer masih mengeluh, jadi kami mengubahnya. Kemudian programmer lain mengeluh.
Pilih saja dan tetap dengan itu. Ada masalah yang lebih besar untuk dipecahkan dalam skema besar untuk mengeluarkan perangkat lunak.
sumber
Option Base
itu konyol, saya memang suka fitur beberapa bahasa yang ditawarkan memungkinkan array untuk secara individual menentukan batas bawah sewenang-wenang. Jika seseorang memiliki array data per tahun, misalnya, melampaui dimensi array[firstYear..lastYear]
bisa lebih baik daripada harus selalu mengakses elemen[thisYear-firstYear]
.Gunakan keduanya.
Jangan campur UI dengan kode inti Anda. Secara internal (sebagai perpustakaan) Anda harus kode "tanpa mengetahui" bagaimana setiap elemen pada array akan dipanggil oleh pengguna akhir. Gunakan array dan koleksi 0-indeks "alami".
Bagian dari program yang menggabungkan data dengan UI, tampilan, harus berhati-hati untuk menerjemahkan data dengan benar antara Model Mental Pengguna dan 'Perpustakaan' yang melakukan pekerjaan yang sebenarnya.
Kenapa ini lebih baik?
sumber
Anda dapat melihat koleksi dari dua sudut yang berbeda.
(1) Ini, pada awalnya, koleksi berurutan biasa , seperti array atau daftar. Indeks dari
0
jelas merupakan solusi yang tepat, setelah konvensi. Anda mengalokasikan cukup entri dan nomor peta saluran untuk indeks, yang sepele (kurangi saja1
).(2) Koleksi Anda pada dasarnya adalah pemetaan antara pengidentifikasi saluran dan objek info saluran. Kebetulan pengidentifikasi saluran adalah kisaran integer berurutan; besok mungkin seperti itu
[1, 2, 3, 3a, 4, 4.1, 6, 8, 13]
. Anda menggunakan set yang dipesan ini sebagai kunci pemetaan.Pilih salah satu pendekatan, dokumentasikan, dan pertahankan. Dari sudut pandang fleksibilitas, saya akan menggunakan (2), karena representasi nomor saluran (setidaknya nama yang ditampilkan) relatif cenderung berubah di masa depan.
sumber
channels[int]
) akan nol diindeks bilangan bulat, dan accesor DapatkanGetChannelByFrequency
,GetChannelByName
,GetChannelByNumber
akan fleksibel.Dictionary
atauSortedDictionary
.operator [] (int index)
harus berbasis 0, sementaraoperator [] (IOrdered index)
tidak. (Permintaan maaf untuk sintaksis perkiraan, C # saya sangat berkarat.)[]
dalam bahasa yang menggunakan kelebihan ini untuk pencarian dengan kunci sewenang-wenang, maka programmer tidak boleh mengasumsikan kunci mulai dari0
dan berdekatan, dan harus menendang kebiasaan itu tajam. Mereka mungkin mulai dari0
, atau1
, atau1000
, string"Channel1"
, itulah inti dari menggunakan operator[]
dengan kunci sewenang-wenang. OTOH, jika ini adalah C dan seseorang berkata "haruskah saya meninggalkan elemen0
dalam array yang tidak digunakan untuk memulai dari1
" maka saya tidak akan mengatakan "jelas, ya", itu akan menjadi panggilan dekat tapi saya akan cenderung untuk "tidak".Semua orang dan anjing mereka menggunakan indeks berbasis nol. Menggunakan indeks berbasis satu di dalam aplikasi Anda akan menyebabkan Anda masalah pemeliharaan selamanya.
Sekarang apa yang Anda tampilkan di antarmuka pengguna, itu sepenuhnya terserah Anda dan klien Anda. Cukup tampilkan i +1 sebagai nomor saluran, bersama dengan saluran #i, jika itu membuat klien Anda senang.
Jika Anda mengekspos kelas, maka Anda mengeksposnya ke programmer. Orang yang Anda bingung dengan indeks berbasis nol bukanlah pemrogram, jadi ada pemutusan di sini.
Anda sepertinya khawatir tentang konversi antara UI dan kode. Jika itu membuat Anda khawatir, buat kelas yang membawa representasi antarmuka pengguna dari nomor saluran. Satu panggilan mengubah angka 12 menjadi representasi UI "Channel 13", dan satu panggilan mengubah "Channel 13" menjadi angka 12. Anda harus tetap melakukannya, jika pelanggan berubah pikiran, jadi hanya ada dua baris kode Untuk mengganti. Dan itu berfungsi jika pelanggan meminta angka romawi, atau huruf A hingga Z.
sumber
Anda mencampurkan dua konsep: pengindeksan dan identitas. Mereka bukan hal yang sama dan tidak boleh bingung.
Apa tujuan dari pengindeksan? Akses acak cepat. Jika kinerjanya tidak menjadi masalah, dan mengingat deskripsi Anda itu bukan masalah, maka menggunakan koleksi yang memiliki indeks tidak perlu dan mungkin tidak disengaja.
Jika Anda (atau tim Anda) dibingungkan oleh indeks vs identitas, maka Anda dapat menyelesaikan masalah itu dengan tidak memiliki indeks. Gunakan kamus atau enumerable dan dapatkan saluran berdasarkan nilainya.
Yang pertama lebih jelas, yang kedua lebih pendek - mereka mungkin atau mungkin tidak diterjemahkan ke dalam IL yang sama, tetapi bagaimanapun, mengingat Anda menggunakan ini untuk dropdown, itu harus cukup cepat.
sumber
Anda mengekspos antarmuka melalui
ChannelSet
kelas yang Anda harapkan berinteraksi dengan pengguna Anda. Saya akan membuatnya sealami mungkin bagi mereka untuk menggunakannya. Jika Anda mengharapkan pengguna Anda akan mulai menghitung dari 1 bukannya 0, maka ekspos kelas ini dan penggunaannya dengan harapan itu dalam pikiran.sumber
Pengindeksan berbasis 0 populer, dan dipertahankan oleh orang-orang penting, karena deklarasi tersebut menunjukkan ukuran objek.
Dengan komputer modern, dengan komputer yang akan digunakan pengguna Anda, apakah ukuran objek itu penting?
Jika bahasa Anda (C #) tidak mendukung cara yang bersih untuk mendeklarasikan elemen pertama dan terakhir dari sebuah array, Anda bisa mendeklarasikan array yang lebih besar, dan menggunakan konstanta yang dideklarasikan (atau variabel dinamis) untuk mengidentifikasi awal dan akhir logis dari area aktif array.
Untuk objek UI, Anda hampir pasti mampu menggunakan objek kamus untuk pemetaan Anda, (jika Anda punya 10 juta objek, Anda punya masalah UI), dan jika objek kamus terbaik ternyata menjadi daftar dengan Membuang banyak ruang di kedua ujungnya, Anda tidak kehilangan sesuatu yang penting.
sumber