Menurut jawaban yang diterima pada " Dasar Pemikiran untuk memilih variabel lokal daripada variabel instan? ", Variabel harus hidup dalam ruang lingkup sekecil mungkin.
Sederhanakan masalahnya menjadi interpretasi saya, artinya kita harus memperbaiki kode semacam ini:
public class Main {
private A a;
private B b;
public ABResult getResult() {
getA();
getB();
return ABFactory.mix(a, b);
}
private getA() {
a = SomeFactory.getA();
}
private getB() {
b = SomeFactory.getB();
}
}
menjadi sesuatu seperti ini:
public class Main {
public ABResult getResult() {
A a = getA();
B b = getB();
return ABFactory.mix(a, b);
}
private getA() {
return SomeFactory.getA();
}
private getB() {
return SomeFactory.getB();
}
}
tetapi menurut "semangat" dari "variabel harus hidup dalam ruang lingkup sekecil mungkin", bukankah "tidak pernah memiliki variabel" memiliki ruang lingkup yang lebih kecil daripada "memiliki variabel"? Jadi saya pikir versi di atas harus di refactored:
public class Main {
public ABResult getResult() {
return ABFactory.mix(getA(), getB());
}
private getA() {
return SomeFactory.getA();
}
private getB() {
return SomeFactory.getB();
}
}
sehingga getResult()
tidak memiliki variabel lokal sama sekali. Benarkah?
refactoring
scope
local-variable
ocomfd
sumber
sumber
final
kata kunci atau tidak.Jawaban:
Tidak. Ada beberapa alasan mengapa:
Dan seterusnya.
sumber
var taxIndex = getTaxIndex();
).now()
,) menghapus variabel dan memanggil metode lebih dari sekali dapat mengakibatkan bug. Ini dapat menciptakan situasi yang sangat halus dan sulit untuk di-debug. Ini mungkin tampak jelas, tetapi jika Anda berada di misi buta refactoring untuk menghapus variabel, mudah untuk akhirnya memperkenalkan kekurangan.Setuju, variabel yang tidak perlu dan tidak meningkatkan keterbacaan kode harus dihindari. Semakin banyak variabel yang berada dalam ruang lingkup pada titik tertentu dalam kode, semakin kompleks kode itu untuk dipahami.
Saya tidak benar-benar melihat manfaat dari variabel
a
danb
dalam contoh Anda, jadi saya akan menulis versi tanpa variabel. Di sisi lain fungsinya sangat sederhana, saya pikir itu tidak penting.Itu menjadi lebih dari masalah, semakin lama fungsinya didapat, dan semakin banyak variabel dalam ruang lingkup.
Misalnya kalau sudah
Di bagian atas fungsi yang lebih besar, Anda meningkatkan beban mental untuk memahami sisa kode dengan memperkenalkan tiga variabel daripada satu. Anda harus membaca sisa kode untuk melihat apakah
a
ataub
digunakan lagi. Warga yang berada dalam ruang lingkup lebih lama dari yang mereka butuhkan buruk untuk keterbacaan keseluruhan.Tentu saja dalam kasus di mana variabel yang diperlukan (misalnya untuk menyimpan hasil sementara) atau di mana variabel tidak meningkatkan pembacaan kode, maka harus disimpan.
sumber
var result = getResult(...); return result;
adalah Anda dapat menggunakan breakpointreturn
dan mempelajari apa sebenarnyaresult
itu.Selain jawaban lain, saya ingin menunjukkan sesuatu yang lain. Manfaat menjaga agar ruang lingkup variabel tetap kecil tidak hanya mengurangi berapa banyak kode yang secara sintaksis memiliki akses ke variabel, tetapi juga mengurangi jumlah jalur alur kontrol yang mungkin dapat mengubah variabel (baik dengan menetapkan nilai baru atau panggilan) metode mutasi pada objek yang ada yang disimpan dalam variabel).
Variabel kelas-lingkup (contoh atau statis) memiliki jalur aliran kontrol yang secara signifikan lebih mungkin daripada variabel-lingkup-lingkup karena mereka dapat dimutasi dengan metode, yang dapat dipanggil dalam urutan apa pun, berapa kali, dan sering dengan kode di luar kelas .
Mari kita lihat
getResult
metode awal Anda :Sekarang, nama-nama
getA
dangetB
mungkin menyarankan bahwa mereka akan menugaskanthis.a
danthis.b
, kita tidak bisa tahu pasti dari hanya melihatgetResult
. Dengan demikian, ada kemungkinan bahwa nilaithis.a
-this.b
nilai dan yang diteruskan ke dalammix
metode bukannya berasal dari keadaanthis
objek dari sebelumnyagetResult
dipanggil, yang tidak mungkin untuk diprediksi karena klien mengontrol bagaimana dan kapan metode dipanggil.Dalam kode yang direvisi dengan variabel lokal
a
danb
, jelas bahwa ada tepat satu (kontrol-bebas) aliran dari penugasan masing-masing variabel untuk penggunaannya, karena variabel dinyatakan tepat sebelum mereka digunakan.Dengan demikian, ada manfaat yang signifikan untuk memindahkan (dapat dimodifikasi) variabel dari kelas-lingkup ke lokal-cakupan (serta memindahkan (dapat dimodifikasi) variabel dari luar loop ke dalam) di mana ia menyederhanakan alasan aliran kontrol.
Di sisi lain, menghilangkan variabel seperti pada contoh terakhir Anda memiliki sedikit manfaat, karena itu tidak benar-benar mempengaruhi penalaran aliran kontrol. Anda juga kehilangan nama yang diberikan ke nilai-nilai, yang tidak terjadi ketika hanya memindahkan variabel ke cakupan dalam. Ini adalah kompromi yang harus Anda pertimbangkan, jadi menghilangkan variabel mungkin lebih baik dalam beberapa kasus, dan lebih buruk pada yang lain.
Jika Anda tidak ingin kehilangan nama variabel, tetapi masih ingin mengurangi cakupan variabel (jika digunakan di dalam fungsi yang lebih besar), Anda dapat mempertimbangkan membungkus variabel dan penggunaannya dalam pernyataan blok ( atau memindahkannya ke fungsinya sendiri ).
sumber
Ini agak tergantung pada bahasa, tetapi saya akan mengatakan bahwa salah satu manfaat yang kurang jelas dari pemrograman fungsional adalah bahwa hal itu mendorong programmer dan pembaca kode untuk tidak memerlukan ini. Mempertimbangkan:
Atau LINQ:
Atau Node.js:
Yang terakhir adalah rantai memanggil fungsi pada hasil fungsi sebelumnya, tanpa variabel perantara. Memperkenalkan mereka akan membuatnya menjadi kurang jelas.
Namun, perbedaan antara contoh pertama dan dua lainnya adalah urutan operasi tersirat . Ini mungkin tidak sama dengan urutan yang sebenarnya dihitung, tetapi urutan di mana pembaca harus memikirkannya. Untuk dua yang kedua ini dari kiri ke kanan. Untuk contoh Lisp / Clojure lebih seperti kanan ke kiri. Anda harus sedikit waspada dalam menulis kode yang tidak berada dalam "arah default" untuk bahasa Anda, dan ekspresi "tengah" yang menggabungkan keduanya harus dihindari.
Operator pipa F #
|>
berguna sebagian karena memungkinkan Anda untuk menulis hal-hal kiri-ke-kanan yang seharusnya harus kanan-ke-kiri.sumber
myCollection.Select(_ => _.SomeProp).Where(_ => _.Size > 4);
Saya akan mengatakan tidak, karena Anda harus membaca "ruang lingkup sekecil mungkin" sebagai "di antara ruang lingkup yang ada atau yang masuk akal untuk ditambahkan". Kalau tidak, itu akan menyiratkan bahwa Anda harus membuat cakupan buatan (misalnya
{}
blok serampangan dalam bahasa seperti C) hanya untuk memastikan bahwa ruang lingkup variabel tidak melampaui penggunaan yang dimaksudkan, dan yang umumnya akan disukai sebagai kekaburan / kekacauan kecuali sudah ada alasan yang baik untuk ruang lingkup ada secara mandiri.sumber
Pertimbangkan fungsi ( metode ). Tidak ada pemisahan kode dalam subtugas sekecil mungkin, tidak juga potongan kode tunggal terbesar.
Ini adalah batas yang berubah-ubah, dengan membatasi tugas-tugas logis, menjadi bagian-bagian yang dapat dikonsumsi.
Hal yang sama berlaku untuk variabel . Menunjukkan struktur data yang logis, menjadi bagian yang dapat dimengerti. Atau juga cukup memberi nama (menyatakan) parameter:
Tetapi tentu saja memiliki deklarasi di atas, dan dua ratus baris lebih lanjut penggunaan pertama saat ini diterima sebagai gaya yang buruk. Ini jelas apa "variabel harus hidup dalam ruang sekecil mungkin" bermaksud mengatakan. Seperti sangat dekat "jangan menggunakan kembali variabel."
sumber
Apa yang agak hilang sebagai alasan untuk TIDAK adalah debugging / readabillity. Kode harus dioptimalkan untuk itu, dan nama-nama yang jelas dan ringkas sangat membantu misalnya bayangkan 3 cara jika
baris ini pendek, tetapi sudah sulit dibaca. Tambahkan beberapa parameter lagi, dan itu jika membentang beberapa baris.
Saya menemukan cara ini lebih mudah untuk membaca dan mengkomunikasikan makna - jadi saya tidak punya masalah dengan variabel perantara.
Contoh lain adalah bahasa seperti R, di mana baris terakhir secara otomatis nilai pengembalian:
ini berbahaya, apakah pengembaliannya dikeluarkan atau diperlukan? ini lebih jelas:
Seperti biasa, ini adalah panggilan penilaian - menghilangkan variabel perantara jika mereka tidak meningkatkan bacaan, sebaliknya menyimpan atau memperkenalkan mereka.
Poin lain bisa menjadi debuggability: Jika hasil perantara menarik, yang terbaik adalah memperkenalkan perantara, seperti dalam contoh R di atas. Seberapa sering hal ini disebut sulit untuk dibayangkan dan berhati-hati dengan apa yang Anda periksa - terlalu banyak variabel debug membingungkan - sekali lagi, panggilan penilaian.
sumber
Mengacu hanya pada judul Anda: tentu saja, jika suatu variabel tidak perlu itu harus dihapus.
Tetapi "tidak perlu" tidak berarti bahwa program yang setara dapat ditulis tanpa menggunakan variabel, jika tidak kita akan diberitahu bahwa kita harus menulis semuanya dalam biner.
Jenis variabel yang tidak perlu yang paling umum adalah variabel yang tidak digunakan, semakin kecil cakupan variabel semakin mudah untuk menentukan bahwa itu tidak perlu. Apakah variabel perantara tidak perlu lebih sulit untuk ditentukan, karena itu bukan situasi biner, itu kontekstual. Sebenarnya kode sumber yang identik dalam dua metode yang berbeda dapat menghasilkan jawaban yang berbeda oleh pengguna yang sama tergantung pada pengalaman masa lalu memperbaiki masalah dalam kode sekitarnya.
Jika kode contoh Anda persis seperti yang diwakili, saya akan menyarankan menyingkirkan dua metode pribadi, tetapi akan sedikit peduli tentang apakah Anda menyimpan hasil panggilan pabrik ke variabel lokal atau hanya menggunakannya sebagai argumen untuk campuran metode.
Keterbacaan kode mengalahkan segalanya kecuali berfungsi dengan benar (termasuk kriteria kinerja yang dapat diterima, yang jarang "secepat mungkin").
sumber