[Catatan: Di bawah ini sedikit C # berat dalam sintaks dan konvensi, seperti mengutip aturan FxCop, karena ini adalah latar belakang saya, tetapi maksud dari diskusi ini adalah untuk menjadi agnostik bahasa dan contoh kode yang digunakan umumnya harus dianggap sebagai kode semu. - Mike]
Saya pikir kita semua akan setuju bahwa kelas umumnya harus dirancang sehingga instance objek mereka tidak berubah di mana pun praktis, dan hasil memanggil anggota kelas harus bebas dari efek samping, sebanyak mungkin.
Akan tetapi, konvensi penamaan historis cenderung menggunakan suara aktif: 'GetSomething', 'DoSomehing', dll. Dan ini bagus karena menyatakan dengan jelas tindakan apa yang akan dilakukan anggota kelas.
Saya sekarang mulai berpikir, bahwa anggota kadang-kadang mungkin (atau mungkin sering) mendapat manfaat dengan disebutkan di masa lalu untuk berkonotasi bahwa nilai dikembalikan tanpa mempengaruhi objek yang direferensikan.
Misalnya, untuk metode yang mentransposkan array, gaya penamaan saat ini mungkin akan menyebutnya 'Array.Transpose', tetapi jika anggota ini mengembalikan array baru , tanpa mentransposisi objek yang direferensikan, maka saya pikir menyebutnya 'Array.Transposed 'Akan lebih akurat dan membuatnya lebih jelas bagi programmer.
Ketika bekerja dengan metode 'Array.Transpose ()' orang mungkin tidak sengaja mencoba menggunakan kode seperti berikut:
Array myArray = new Array();
myArray.Transpose();
Tetapi jika metode 'Transpose' mengembalikan array baru tanpa memengaruhi objek yang direferensikan, maka kode ini tidak melakukan apa pun - yaitu, 'myArray' akan diam-diam tidak dipindahkan. (Saya kira jika 'Transpose' adalah properti, maka kompiler akan mengetahui bahwa hal di atas tidak sah, tetapi pedoman FxCop menyatakan bahwa anggota yang melakukan konversi harus menjadi metode.)
Tetapi jika metode ini dinamai dalam bentuk lampau sebagai 'Array.Transposed', akan lebih jelas bagi pengguna bahwa sintaks berikut diperlukan:
Array myArray = new Array();
Array transposedArray = myArray.Transposed();
Nama lain yang saya pikir akan masuk dalam kategori ini adalah anggota yang diberi nama 'Resize' vs 'Resize', 'Shifted' vs 'Shift', dll. Present tense akan digunakan untuk anggota yang mempengaruhi objek yang direferensikan, sedangkan past tense akan digunakan untuk anggota yang mengembalikan nilai baru tanpa memengaruhi objek yang direferensikan.
Pendekatan lain yang lebih umum saat ini adalah untuk mengawali setiap nama dengan "Get" atau "To", tapi saya pikir ini menambah bobot yang tidak perlu, sementara mengubah ke past tense mengkomunikasikan artinya secara efektif.
Apakah ini masuk akal bagi programmer lain di sini, atau apakah ide lampau ini terdengar terlalu canggung saat membacanya?
Edit:
Diskusi hebat di bawah ini, saya berterima kasih banyak kepada semua orang. Beberapa poin yang ingin saya rangkum berdasarkan komentar Anda dan pemikiran saya sendiri yang direvisi mengenai hal ini di bawah ini.
Metode Chaining Sintaks "Fasih"
Berdasarkan diskusi di bawah ini, penggunaan past tense mungkin bernilai ketika digunakan pada kelas yang bisa berubah untuk memperjelas anggota mana yang melakukan, atau tidak, mempengaruhi keadaan internal objek yang direferensikan.
Namun, untuk kelas yang tidak berubah, yang seharusnya menjadi mayoritas kasus (orang akan berharap), saya berpikir bahwa penggunaan past tense dapat membuat sintaksisnya menjadi canggung.
Misalnya, dengan "sintaks yang lancar" seperti yang dibuat dengan metode chaining, penggunaan past tense akan membuat kode lebih mudah dibaca. Misalnya, ketika menggunakan LINQ melalui C #, rantai metode yang khas bisa terlihat sebagai berikut:
dataSource.Sort().Take(10).Select(x => x.ToString);
Jika diubah ke bentuk lampau, ini akan menjadi canggung:
dataSource.Sorted().Taken(10).Selected(x => x.ToString);
Ingat, dataSource.Sorted () sebenarnya lebih jelas artinya daripada dataSource.Sort (), karena ekspresi LINQ selalu membuat enumerasi baru tanpa mempengaruhi sumber. Namun, karena kita sepenuhnya menyadari hal ini ketika menggunakan paradigma ini, penggunaan bentuk lampau itu berlebihan dan membuat "kelancaran" membacanya dengan canggung tanpa hasil nyata.
Penggunaan Properti vs. Metode
Masalah utama yang muncul di bawah ini berkaitan dengan pedoman FxCop untuk penggunaan metode "Get" vs. properti read-only. Misalnya, aturan FxCop CA1024 .
Meskipun tidak disebutkan secara eksplisit dalam aturan FxCop itu, penggunaan metode "To" juga berlaku untuk alasan ini, karena metode ToXXXXXX () adalah metode konversi. Dan dalam kasus ToArray (), metode ini adalah metode konversi dan juga metode yang mengembalikan array.
Penggunaan Past Tense untuk Properti Boolean
Beberapa menyarankan bahwa past tense dapat berkonotasi dengan nilai boolean, misalnya properti 'Succeeded' atau 'Connected'. Saya percaya bahwa retort di bawah ini menekankan penggunaan 'Is', 'Has', atau 'Are' untuk properti dan bidang Boolean adalah benar. Past tense dapat membantu dalam hal ini juga, tetapi tidak sebanyak menggunakan awalan 'Is'. Jangan ragu untuk menggunakan bentuk lampau untuk properti dan bidang Boolean, itu memang membantu, tapi saya pikir itu lebih penting untuk mengawali nama dengan 'Is', 'Has', atau 'Are'.
Kesimpulan Keseluruhan?
Untuk masalah Tranpose () vs Transposed (), saya pikir 'skizzy' sudah benar, menyarankan bahwa itu harus Transpose () untuk tindakan bermutasi vs GetTransposed () untuk hasil yang tidak bermutasi. Ini membuatnya 100% jelas. Tapi, sekali lagi, saya pikir ini mungkin hanya berlaku untuk kelas yang berkualitas, seperti array.
Untuk kelas yang tidak dapat diubah, terutama di mana sintaks metode chaining yang lancar dapat digunakan, maka saya berpikir bahwa sintaks ini akan menjadi canggung yang tidak perlu. Sebagai contoh, bandingkan:
var v = myObject.Transpose().Resize(3,5).Shift(2);
untuk:
var v = myObject.GetTransposed().GetResized(3,5).GetShifted(2);
Hmmm ... sebenarnya, bahkan di sini tampaknya membuatnya 100% jelas bahwa hasilnya tidak mempengaruhi sumbernya, tapi saya tidak yakin.
Saya kira untuk paradigma seperti LINQ yang sudah dikenal luas, penggunaan "Get" dan / atau past tense tidak diperlukan, tetapi untuk API baru, mungkin ada nilainya - pada awalnya! Jika API hanya berisi objek yang tidak dapat diubah, setelah pengguna memahami ini, penggunaan "Get" dan / atau past tense hanya akan mengurangi keterbacaan.
Jadi saya pikir tidak ada jawaban yang mudah di sini. Saya kira orang perlu memikirkan keseluruhan API Anda dan memilih dengan hati-hati!
- Mike
Jawaban:
Past-tense agak terdengar canggung. Saya pikir Anda bermaksud kata itu menjadi kata sifat.
Ini saran saya untuk masalah yang Anda minta: alih-alih
Transpose()
, panggil sajaGetTransposed()
. Dengan begitu, Anda tahu bahwa Anda menerima sesuatu dan tidak memodifikasi objek.sumber
Transpose()
ini masih bisa diartikan sebagai menyesuaikan objek yang diberikan. Mungkin ini harus menjadi konstruksi bahasa. :)object.Transpose()
vsobject:Transpose()
.AsTransposed
suka daripadaGetTransposed
untuk kasus di mana panggilan berulang berulang akan, tanpa efek samping, menghasilkan hasil yang identik secara semantik (yang mungkin atau mungkin bukan objek yang sama, tetapi tidak dapat ditampilkan sebagai objek yang berbeda tanpa menggunakan hal-hal sepertiReferenceEquals
atau yang setara) .Itu memang masuk akal.
Apa yang Anda bicarakan, menurut pendapat saya, harus diambil sebagai aturan umum saat merancang API atau perpustakaan. Hanya kemudian akan menawarkan manfaat nyata jika sistem ini konsisten di semua kelas.
Masalah lain adalah bahwa dalam banyak kasus, pengguna antarmuka tidak begitu peduli tentang bagaimana hasil dicapai.
Akankah Transpose () memindahkan objek yang sekarang? Akankah Transpose () membuat turunan contoh yang baru dan mengembalikan referensi ke sana? Atau akankah mungkin ditransformasikan satu kali, menyimpan hasil dalam salinan dan mengembalikannya pada panggilan berikutnya tanpa mempengaruhi objek saat ini?
Pengguna sering hanya ingin mendapatkan hasil yang dialihkan, itulah sebabnya tidak banyak yang akan peduli dengan konvensi penamaan yang Anda usulkan.
Tetapi dengan sendirinya, itu adalah proposal yang valid.
sumber
Saya sangat tidak setuju. Bentuk lampau canggung dan tidak umum digunakan (yang merupakan alasan cukup untuk tidak memilihnya).
Jika metode ini memodifikasi objek yang dipanggil, ia tidak seharusnya kembali sendiri - ini membuatnya jelas bahwa itu memodifikasi objek.
Demikian juga, jika metode tidak mengubah objek yang dipanggil dan sebagai gantinya membangun objek baru, metode akan mengembalikan objek dengan tipe yang sama. Ini adalah konvensi yang jelas dan sudah umum.
Menurut saya, metode signature adalah konvensi yang lebih jelas dan lebih umum digunakan untuk menunjukkan apakah metode mengembalikan objek baru atau memodifikasi callee.
sumber
Kedengarannya masuk akal, dan ada preseden - Python memiliki keduanya
list.sort()
dansorted(seq)
. Yang pertama adalah metode, yang lain adalah fungsi yang bekerja pada setiap iterable dan mengembalikan daftar.sumber
Di perpustakaan koleksi Scala, ada beberapa metode yang di masa lalu:
grouped
mengembalikan sebuah iterator yang beralih pada elemen-elemen dari suatu urutan dalam potongann
elemensorted
mengembalikan versi koleksi yang diurutkanupdated
mengembalikan versi baru koleksi dengan satu elemen berubahNamun, saya tidak yakin apakah ini keputusan sadar atau apakah mereka kehabisan nama, karena perpustakaan koleksi Scala sangat kaya. Sebagai contoh, ada juga
groupBy
dansortBy
metode, danupdate
metode ini khusus, karena kompiler menulis ulang tugaske
Versi Scala memang melakukan penggunaan
update
untuk koleksi berubah, tetapi memilikiupdate
kembali versi baru bukan bermutasi sangat canggung, karena Anda jelas harus menetapkan nilai kembali ke sesuatu, jadi misalnya "memperbarui" entri dalam peta abadi akan menjadi sesuatu SukaSekarang ya
Dalam bahasa dengan sistem tipe yang baik, tipe tersebut biasanya akan memberi tahu Anda apakah rutin mengubah mutasi argumennya. Di Haskell, misalnya, tipe dari versi yang tidak dapat diubah adalah sesuatu seperti
sedangkan versi yang bisa berubah akan seperti
sumber
Ketika saya melihat metode / properti dalam bentuk berlalu saya segera menganggap itu mengembalikan boolean. Proposal Anda mungkin masuk akal secara logis, tetapi sepertinya aneh dan canggung. Jika saya harus menjelaskan kepada seseorang mengapa masuk akal itu mungkin bukan konvensi yang baik.
sumber
Saya bukan penggemar nama variabel masa lampau untuk kekekalan - ini adalah konvensi yang agak tidak biasa dan saya pikir itu akan menyebabkan kebingungan, terutama bagi orang-orang yang tidak terlalu kuat dalam tata bahasa Inggris (dan saya hanya bercanda setengah) sana...)
Juga, konvensi ini menghilangkan peluang menggunakan past tense untuk menunjukkan sesuatu yang lain yang menurut saya lebih penting: deskripsi keadaan objek yang dijelaskan, misalnya "barang yang diproses" dengan jelas memberi tahu Anda bahwa item dalam koleksi sudah diproses, yang merupakan informasi logis penting untuk disampaikan.
Ide yang lebih baik: membuat semuanya tidak berubah . Maka Anda tidak perlu perbedaan bahasa mewah. Anda tahu Anda ingin :-)
sumber