Adakah argumen rekayasa-perangkat lunak yang obyektif dan dapat didukung untuk atau tidak memodifikasi nilai-nilai parameter nilai-dalam tubuh suatu fungsi?
Ludah berulang (sebagian besar menyenangkan) di tim saya adalah apakah parameter yang dilewati oleh nilai harus dimodifikasi atau tidak. Beberapa anggota tim bersikeras bahwa parameter tidak boleh ditugaskan, sehingga nilai yang semula diberikan ke fungsi selalu dapat diinterogasi. Saya tidak setuju dan berpendapat bahwa parameter tidak lebih dari variabel lokal yang diinisialisasi oleh sintaks memanggil metode; jika nilai asli dari parameter menurut nilai penting dari variabel lokal dapat dinyatakan untuk secara eksplisit menyimpan nilai ini. Saya tidak yakin bahwa kami berdua memiliki dukungan yang sangat baik untuk posisi kami.
Apakah ini konflik agama yang tak terselesaikan, atau adakah alasan rekayasa perangkat lunak objektif yang baik di kedua arah?
Catatan: Pertanyaan prinsip tetap terlepas dari detail implementasi bahasa tertentu. Dalam JavaScript, misalnya, di mana daftar argumen selalu dinamis, parameter dapat dianggap sebagai gula sintaksis untuk inisialisasi variabel lokal dari arguments
objek. Meski begitu, orang dapat memperlakukan pengidentifikasi yang dinyatakan parameter sebagai "khusus" karena mereka masih menangkap berlalunya informasi dari penelepon ke callee.
sumber
Jawaban:
Saya mengadopsi posisi ketiga: parameter sama seperti variabel lokal: keduanya harus diperlakukan tidak berubah secara default. Jadi variabel ditugaskan satu kali dan kemudian hanya membaca dari, tidak diubah. Dalam kasus loop,
for each (x in ...)
variabel tidak dapat diubah dalam konteks setiap iterasi. Alasan untuk ini adalah:Dihadapkan dengan metode dengan sekelompok variabel yang ditugaskan dan kemudian tidak berubah, saya dapat fokus membaca kode, daripada mencoba mengingat nilai saat ini dari masing-masing variabel tersebut.
Dihadapkan dengan metode yang sama, kali ini dengan lebih sedikit variabel, tetapi itu mengubah nilai sepanjang waktu, saya sekarang harus mengingat keadaan saat ini dari variabel-variabel tersebut, serta bekerja pada apa yang dilakukan kode.
Dalam pengalaman saya, yang pertama jauh lebih mudah di otak saya yang buruk. Lainnya, lebih pintar, orang lain daripada saya mungkin tidak memiliki masalah ini, tetapi itu membantu saya.
Adapun poin lainnya:
melawan
Contoh-contoh yang dibuat, tetapi bagi saya jauh lebih jelas mengenai apa yang terjadi dalam contoh kedua karena nama variabel: mereka memberikan informasi yang jauh lebih banyak kepada pembaca daripada massa yang
r
melakukan dalam contoh pertama.sumber
for
loop dengan variabel yang tidak dapat diubah. Meringkas variabel dalam fungsi tidak cukup untuk Anda? Jika Anda mengalami kesulitan mengikuti variabel Anda dalam fungsi belaka, mungkin fungsi Anda terlalu panjang.for (const auto thing : things)
adalah untuk loop, dan variabel yang diperkenalkannya adalah (secara lokal) tidak berubah.for i, thing in enumerate(things):
juga tidak bermutasi setiap penduduk setempatItu satu hal yang saya sangat suka tentang (ditulis dengan baik) C ++: Anda dapat melihat apa yang diharapkan.
const string& x1
adalah referensi konstan,string x2
adalah salinan danconst string x3
salinan konstan. Saya tahu apa yang akan terjadi dalam fungsi tersebut.x2
akan diubah, karena jika tidak, tidak akan ada alasan untuk membuatnya non-const.Jadi jika Anda memiliki bahasa yang memungkinkannya , nyatakan apa yang akan Anda lakukan dengan parameternya. Itu harus menjadi pilihan terbaik bagi semua orang yang terlibat.
Jika bahasa Anda tidak memungkinkan ini, saya khawatir tidak ada solusi peluru perak. Keduanya mungkin. Satu-satunya pedoman adalah prinsip kejutan paling tidak. Ambil satu pendekatan dan lakukan dengan itu di seluruh basis kode Anda, jangan campur.
sumber
int f(const T x)
danint f(T x)
hanya berbeda dalam fungsi-tubuh.const int x
hanya untuk membuat jelas x tidak diubah di dalamnya? Sepertinya gaya yang sangat aneh bagi saya.const
jauh dari daftar parameter jika itu menghambatnya. Jadi saya tidak berpikir ini menjawab pertanyaan.Ya, itu adalah "konflik agama", kecuali bahwa Tuhan tidak membaca program (sejauh yang saya tahu), jadi itu diturunkan menjadi konflik keterbacaan yang menjadi masalah penilaian pribadi. Dan saya tentu saja telah melakukannya, dan melihatnya berhasil, keduanya. Sebagai contoh,
Jadi di sini, hanya karena nama argumen t0 , saya cenderung memilih untuk tidak mengubah nilainya. Tapi anggap saja, kita hanya mengubah nama argumen itu menjadi tNow , atau sesuatu seperti itu. Lalu saya lebih mungkin lupa tentang salinan lokal dan hanya menulis tNow + = dt; untuk pernyataan terakhir itu.
Tetapi sebaliknya, seandainya saya tahu bahwa klien yang menulis program ini akan mempekerjakan beberapa programmer baru dengan pengalaman yang sangat sedikit, yang akan membaca dan mengerjakan kode itu. Maka saya mungkin khawatir tentang membingungkan mereka dengan pass-by-value versus-referensi, sementara pikiran mereka 100% sibuk mencoba untuk mencerna semua logika bisnis. Jadi dalam kasus seperti ini saya selalu mendeklarasikan salinan lokal dari setiap argumen yang akan diubah, terlepas dari apakah itu lebih atau kurang dapat dibaca oleh saya.
Jawaban untuk pertanyaan gaya semacam ini muncul dengan pengalaman, dan jarang memiliki jawaban agama kanonik. Siapa pun yang mengira ada satu-dan-hanya-satu jawaban (dan bahwa ia mengetahuinya) mungkin perlu lebih banyak pengalaman.
sumber