Apakah cukup untuk metode dibedakan hanya dengan nama argumen (bukan tipe) atau lebih baik untuk nama lebih eksplisit?
Misalnya T Find<T>(int id)
vs T FindById<T>(int id)
.
Apakah ada alasan yang baik untuk menamainya lebih eksplisit (yaitu menambahkan ById
) vs mempertahankan nama argumen yang adil?
Salah satu alasan yang bisa saya pikirkan adalah ketika tanda tangan dari metode yang sama tetapi mereka memiliki makna yang berbeda.
FindByFirstName(string name)
dan FindByLastName(string name)
T Find<T>(string name)
atau(int size)
bagaimana Anda berencana untuk menyelesaikan masalah yang tak terhindarkan?ID
objek buram dan bukan hanya sebuahint
. Dengan cara itu dapatkan waktu kompilasi memeriksa bahwa Anda tidak menggunakan id untuk int atau sebaliknya di beberapa bagian kode Anda. Dan dengan itu Anda dapat memilikifind(int value)
danfind(ID id)
.Jawaban:
Tentu ada alasan bagus untuk menyebutkannya secara lebih eksplisit.
Ini terutama bukan definisi metode yang harus jelas, tetapi metode yang digunakan . Dan sementara
findById(string id)
danfind(string id)
keduanya cukup jelas, ada perbedaan besar antarafindById("BOB")
danfind("BOB")
. Dalam kasus sebelumnya Anda tahu bahwa literal acak, pada kenyataannya, adalah ID. Dalam kasus terakhir Anda tidak yakin - itu mungkin sebenarnya nama yang diberikan atau sesuatu yang lain sama sekali.sumber
findById(id)
vsfind(id)
. Anda dapat melakukannya dengan cara ini.double Divide(int numerator, int denominator)
yang digunakan dalam metode:double murdersPerCapita = Divide(murderCount, citizenCount)
. Anda tidak dapat mengandalkan dua metode menggunakan nama variabel yang sama karena ada banyak kasus di mana itu tidak terjadi (atau ketika itu terjadi, itu penamaan yang buruk)Keuntungan FindById () .
Masa depan-pemeriksaan : Jika Anda memulai dengan
Find(int)
, dan kemudian harus menambahkan metode lain (FindByName(string)
,FindByLegacyId(int)
,FindByCustomerId(int)
,FindByOrderId(int)
, dll), orang-orang seperti saya cenderung menghabiskan usia mencariFindById(int)
. Tidak benar-benar masalah jika Anda bisa dan akan berubahFind(int)
menjadiFindById(int)
begitu diperlukan - pemeriksaan di masa depan adalah tentang ini jika s.Lebih mudah dibaca .
Find
baik-baik saja jika panggilannya sepertirecord = Find(customerId);
NamunFindById
sedikit lebih mudah untuk dibaca jika iturecord = FindById(AFunction());
.Konsistensi . Anda dapat secara konsisten menerapkan
FindByX(int)
/FindByY(int)
pola di mana-mana, tetapiFind(int X)
/Find(int Y)
tidak mungkin karena mereka bertentangan.Keuntungan Menemukan ()
Find
sederhana dan mudah, dan di sampingoperator[]
itu salah satu dari 2 nama fungsi yang paling diharapkan dalam konteks ini. (Beberapa alternatif populer menjadiget
,lookup
ataufetch
, tergantung pada konteks).FindById(int id)
, kita dapat dengan mudah menghapus redundansi dengan mengubahnyaFind(int id)
, tetapi ada trade off - kita kehilangan kejelasan.Atau Anda bisa mendapatkan keuntungan dari keduanya dengan menggunakan Id yang sangat diketik:
Implementasi
Id<>
: Sangat mengetik nilai ID di C #Komentar di sini, serta di link di atas, mengangkat beberapa kekhawatiran tentang
Id<Customer>
bahwa saya ingin alamat:CustomerId
danOrderID
tipe yang berbeda (customerId1 = customerId2;
=> baik,customerId1 = orderId1;
=> buruk), tetapi implementasinya hampir identik, sehingga kami dapat mengimplementasikannya baik dengan salin tempel atau dengan metaprogramming. Meskipun ada nilai dalam diskusi tentang mengekspos atau menyembunyikan generik, metaprogramming adalah tujuan generik.DoSomething(int customerId, int orderId, int productId)
. Id yang diketik dengan kuat juga mencegah masalah lain, termasuk yang ditanyakan OP.int aVariable
. Sangat mudah untuk mengetahui bahwa ID telah disimpanId<Customer> aVariable
, dan kami bahkan dapat mengatakan bahwa itu adalah ID pelanggan.String
hanyalah pembungkus di sekitarbyte[]
. Pembungkus, atau enkapsulasi, tidak bertentangan dengan pengetikan yang kuat.operator==
danoperator!=
juga, jika Anda tidak ingin bergantung secara eksklusif padaEquals
:.
sumber
Cara lain untuk berpikir tentang ini adalah dengan menggunakan jenis keamanan bahasa.
Anda dapat menerapkan metode seperti:
Di mana FirstName adalah objek sederhana yang membungkus string yang berisi nama depan dan berarti tidak ada kebingungan tentang apa yang dilakukan metode ini, atau dalam argumen yang disebutnya.
sumber
string name = "Smith"; findById(name);
dimungkinkan jika Anda menggunakan tipe umum non-deskriptif.DWORD
LPCSTR
klon dll yang tak berujung dan berpikir "ini adalah int / string / dll." .int
s sering dijumlahkan, dikalikan, dll. Yang tidak berarti untuk ID; jadi saya akan membuatnyaID
berbedaint
. Ini dapat menyederhanakan API, dengan mempersempit apa yang dapat kita lakukan dengan memberikan nilai (mis. Jika kita memilikiID
, itu hanya akan berfungsifind
, bukan misalnyaage
atauhighscore
). Sebaliknya, jika kita mendapati diri kita banyak berkonversi, atau menulis fungsi / metode yang sama (mis.find
) Untuk banyak jenis, itu adalah tanda bahwa perbedaan kita terlalu baikSaya akan memilih deklarasi eksplisit seperti FindByID .... Perangkat lunak harus dibangun untuk Perubahan. Itu harus terbuka dan tertutup (SOLID). Jadi kelas terbuka untuk menambahkan metode menemukan yang mirip seperti katakanlah FindByName .. dll.
Tetapi FindByID ditutup dan implementasinya diuji unit.
Saya tidak akan menyarankan metode dengan predikat, itu bagus di tingkat generik. Bagaimana jika berdasarkan bidang (ByID) Anda memiliki metodologi yang berbeda lengkap.
sumber
Saya terkejut tidak ada yang menyarankan untuk menggunakan predikat seperti berikut:
Dengan pendekatan ini tidak hanya Anda mengurangi permukaan API Anda, tetapi juga memberikan lebih banyak kontrol kepada pengguna yang menggunakannya.
Jika itu tidak cukup, Anda selalu dapat mengembangkannya sesuai kebutuhan Anda.
sumber