Apakah masuk akal bagi seorang refactor untuk mendapatkan LOC yang lebih tinggi? [Tutup]

25

Apakah ada kasus di mana kode verbose lebih banyak (seperti dalam pernyataan yang lebih logis) lebih bersih daripada kode lebih ringkas?

nama pengguna salah
sumber
18
Tentu saja. Bahkan ketika menghilangkan duplikasi, kode untuk mendefinisikan fungsi baru yang diekstraksi membutuhkan ruang tersendiri. Menulis fungsi baru dapat mengambil empat baris dan menyimpan hanya dua, dan masih menjadi hal yang bermanfaat untuk dilakukan.
Kilian Foth
5
"kode lebih ringkas"? Saya benar-benar membenci keyakinan yang salah arah bahwa jumlah baris yang lebih kecil berarti kode "lebih baik". Tidak. Bahkan, biasanya sebaliknya. Ada satu titik - dan itu dicapai sangat cepat - di mana menjejalkan semakin banyak makna ke dalam semakin sedikit ruang membuat kode semakin sulit untuk dipahami. Faktanya, ada seluruh kompetisi - Kontes Kode C yang Dikacaukan Internasional - di mana banyak pemenang bergantung pada batas-batas pemahaman manusia untuk menulis kode yang tidak bisa ditembus.
Andrew Henle
1
Judul pertanyaan Anda dan pertanyaan Anda sendiri menanyakan berbagai pertanyaan. Misalnya, pernyataan if dapat diubah menjadi ekspresi ternary yang sama secara logis tetapi hanya 1 baris.
Kapten Man
1
-1 *** kode verbose lebih banyak (seperti dalam pernyataan yang lebih logis) *** verbositas dan jumlah pernyataan logis adalah dua hal yang tidak terkait. Bentuk yang buruk untuk mengubah definisi.
Pieter B

Jawaban:

70

Untuk menjawab itu, mari kita ambil contoh dunia nyata yang terjadi pada saya. Di C # perpustakaan yang saya pelihara, saya memiliki kode berikut:

TResult IConsFuncMatcher<T, TResult>.Result() =>
    TryCons(_enumerator) is var simpleMatchData && !simpleMatchData.head.HasValue
        ? _emptyValue.supplied
            ? _emptyValue.value
            : throw new NoMatchException("No empty clause supplied");
        : _recursiveConsTests.Any() 
            ? CalculateRecursiveResult() 
            : CalculateSimpleResult(simpleMatchData);

Membahas hal ini dengan teman sebaya, putusan bulat adalah bahwa ekspresi terner bersarang, ditambah dengan penggunaan "pintar" is varmenghasilkan kode singkat, tetapi sulit dibaca.

Jadi saya refactored ke:

TResult IConsFuncMatcher<T, TResult>.Result()
{
    var simpleMatchData = TryCons(_enumerator);

    if (!simpleMatchData.head.HasValue)
    {
        return _emptyValue.supplied
            ? _emptyValue.value
            : throw new NoMatchException("No empty clause supplied");
    }

    return _recursiveConsTests.Any() 
        ? CalculateRecursiveResult() 
        : CalculateSimpleResult(simpleMatchData);
}

Versi asli berisi hanya satu ekspresi majemuk dengan implisit return. Versi baru sekarang berisi deklarasi variabel eksplisit, ifpernyataan dan dua eksplisit returns. Ini berisi lebih banyak pernyataan dan lebih banyak baris kode. Namun semua orang yang saya berkonsultasi menganggapnya lebih mudah dibaca dan beralasan, yang merupakan aspek kunci dari "kode bersih".

Jadi jawaban untuk pertanyaan Anda adalah "ya" tegas, lebih banyak verbose bisa lebih bersih daripada kode ringkas dan dengan demikian merupakan refactoring yang valid.

David Arno
sumber
34
Di zaman sekarang ini, otak pengembang adalah sumber daya yang lebih langka daripada disk, CPU, RAM, atau bandwidth jaringan. Hal-hal lain itu penting, dan dalam aplikasi tertentu itu mungkin menjadi faktor pembatas Anda, tetapi dalam kebanyakan kasus, Anda ingin mengoptimalkan kemampuan pengembang Anda untuk memahami kode terlebih dahulu , dan kemudian hal-hal lainnya.
anaximander
2
@anaximander, Sepenuhnya setuju. Tulis kode untuk dibaca orang lain terlebih dahulu dan kompiler kedua. Itulah sebabnya saya merasa berguna untuk meminta orang lain meninjau kode saya, meskipun saya satu-satunya yang mengembangkannya.
David Arno
4
Jika saya meninjau itu, saya akan menyarankan membalik urutan pernyataan pengembalian dan menghapusnya !dari kondisi. Saya juga menyarankan menempatkan pengembalian kedua dalam else. Tetapi bahkan ketika berdiri, itu adalah peningkatan besar-besaran.
Martin Bonner mendukung Monica
2
@ DavidArno Saya melihat logika itu, dan jika if (!foo.HasValue)merupakan idiom dalam kode Anda, bahkan lebih kuat lagi. Namun iftidak benar-benar keluar-awal - itu adalah "melakukan ini atau itu tergantung."
Martin Bonner mendukung Monica
2
@fabrikasi Membandingkan nilai boolean berbahaya. Saya menghindarinya sebisa mungkin.
Martin Bonner mendukung Monica
30

1. Kurangnya korelasi antara LOC dan kualitas kode.

Tujuan dari refactoring adalah untuk meningkatkan kualitas sepotong kode.

LOC adalah metrik yang sangat mendasar yang, kadang-kadang, berkorelasi dengan kualitas sepotong kode: misalnya, metode dengan beberapa ribu LOC cenderung memiliki masalah kualitas. Perlu dicatat, bagaimanapun, bahwa LOC bukan satu - satunya metrik, dan dalam banyak kasus tidak memiliki korelasi dengan kualitas. Misalnya, metode 4 LOC tidak selalu lebih mudah dibaca atau lebih dapat dipelihara daripada metode 6 LOC.

2. Beberapa teknik refactoring terdiri dari penambahan LOC.

Jika Anda mengambil daftar teknik refactoring , Anda dapat dengan mudah menemukan teknik yang terdiri dari penambahan LOC secara sengaja . Contoh:

Keduanya adalah teknik refactoring yang sangat berguna, dan pengaruhnya terhadap LOC benar-benar tidak relevan ketika mempertimbangkan apakah akan menggunakannya atau tidak.

Hindari menggunakan LOC.

LOC adalah metrik yang berbahaya. Sangat mudah untuk diukur, dan sangat sulit untuk ditafsirkan dengan benar.

Sampai Anda menjadi terbiasa dengan teknik pengukuran kualitas kode, pertimbangkan untuk menghindari mengukur LOC di tempat pertama. Sebagian besar waktu, Anda tidak akan mendapatkan apa pun yang relevan, dan akan ada kasus di mana itu akan menyesatkan Anda untuk menurunkan kualitas kode Anda.

Arseni Mourzenko
sumber
Anda refactored jawaban Anda dan meningkatkan kualitas dengan menambahkan lebih banyak LOT (baris teks): p
grinch
12

Jika Anda ingin melihat hasil akhir dari hanya meminimalkan jumlah byte atau jumlah LoC dari kode sumber Anda, silakan lihat kiriman ke situs Golf Kode Stack Exchange .

Jika kode sumber Anda dikurangi sedemikian rupa, Anda akan segera mengalami kekacauan yang tidak dapat dipertahankan. Bahkan jika Anda adalah orang yang menulis kode seperti itu, dan memahaminya sepenuhnya pada saat itu, seberapa efisienkah Anda ketika Anda kembali ke kode itu dalam waktu enam bulan? Tidak ada bukti bahwa kode minimal tersebut benar-benar mengeksekusi lebih cepat baik.

Kode harus ditulis sedemikian rupa sehingga setiap anggota tim Anda dapat melihatnya, dan memahami apa yang dilakukannya segera.

Dr luar negeri
sumber
Mungkin berlebihan, tetapi hanya untuk mengejanya; jika Anda refactor kode golf agar mudah dibaca Anda selalu berakhir dengan lebih banyak LoC
JollyJoker
1

Ya refactoring pasti dapat menghasilkan lebih banyak baris kode.

Kasus IMO yang paling umum adalah ketika Anda mengambil kode yang tidak generik dan Anda membuatnya lebih generik / fleksibel . Pembuatan kode secara mudah membuat garis kode meningkat secara signifikan (terkadang dengan faktor dua atau lebih).

Jika Anda mengharapkan kode generik yang baru untuk digunakan oleh orang lain (bukan hanya sebagai komponen perangkat lunak internal) sebagai pustaka, maka Anda biasanya akan menambahkan kode yang belum dikirim dan markup dokumentasi dalam kode yang akan menambah baris kode lagi.

Misalnya, inilah skenario yang sangat umum terjadi pada setiap pengembang perangkat lunak:

  • produk Anda membutuhkan fitur baru prioritas tinggi atau perbaikan bug atau peningkatan dalam dua minggu (atau kerangka waktu apa pun yang dianggap mendesak untuk ukuran proyek / ukuran perusahaan / dll)
  • Anda bekerja keras dan memberikan XYZ tepat waktu dan berfungsi. Selamat! Kerja bagus!
  • Ketika Anda sedang mengembangkan XYZ desain / implementasi kode yang ada tidak benar-benar mendukung XYZ tetapi Anda dapat memasukkan XYZ ke basis kode
  • masalahnya adalah bahwa shim jelek dan memiliki bau kode yang mengerikan karena Anda melakukan beberapa hal yang rumit / pintar / jelek / buruk-praktek-tetapi-agak-bekerja
  • ketika Anda menemukan waktu kemudian Anda refactor kode yang dapat mengubah banyak kelas atau menambahkan lapisan baru kelas dan solusi baru Anda "dilakukan dengan benar" dan tidak memiliki bau kode yang buruk lagi ... namun melakukannya dengan "jalan yang benar" sekarang mengambil lebih banyak baris kode.

Beberapa contoh nyata yang muncul di kepala saya:

  • untuk antarmuka baris perintah Anda dapat memiliki 5000 baris kode if / else-if atau Anda dapat menggunakan panggilan balik ... setiap panggilan balik akan jauh lebih kecil dan lebih mudah dibaca / test / verifikasi / debug / dll tetapi jika Anda menghitung baris dari kode 5000 baris jelek kode if / else-if mungkin akan lebih kecil
  • untuk bagian pemrosesan kode yang mendukung metode pemrosesan N , Anda dapat kembali menggunakan pernyataan if / else yang akan terlihat paling jelek ...
    • atau Anda dapat beralih ke panggilan balik yang akan lebih bagus / lebih baik tetapi panggilan balik mengambil lebih banyak baris kode (masih mengkompilasi waktu)
    • atau Anda bisa abstrak lebih lanjut dan melakukan plugin yang dapat diubah saat runtime. plugin bagus karena Anda tidak perlu mengkompilasi ulang produk utama untuk setiap plugin baru atau modifikasi ke plugin yang ada. dan Anda dapat menerbitkan API sehingga orang lain dapat memperluas produk. TAPI lagi pendekatan plugin menggunakan lebih banyak baris kode.
  • untuk GUI Anda membuat widget baru yang hebat
    • Anda atau rekan kerja mencatat bahwa widget baru akan bagus untuk XYZ dan ABC tetapi saat ini widget tersebut terintegrasi dengan ketat hanya untuk bekerja untuk XYZ
    • Anda memperbaiki widget agar berfungsi untuk keduanya tetapi sekarang total baris kode bertambah
Trevor Boyd Smith
sumber