Bagaimana seseorang mengukur pemeliharaan secara bermakna?

23

Konteks: Saya seorang pengembang perusahaan di semua toko MS.

Adakah yang bisa merekomendasikan cara yang baik untuk secara obyektif mengukur rawatan sepotong kode atau aplikasi?

Mengapa pemeliharaan : Saya bosan dengan metrik "kualitas" di grup saya yang hanya berkisar pada jumlah bug dan cakupan kode. Kedua metrik mudah untuk dimainkan, terutama saat Anda tidak mengukur kemampuan perawatan. Kepicikan dan tenggat waktu menghasilkan sejumlah besar hutang teknis yang tidak pernah benar-benar ditangani.

Mengapa kemampuan untuk mengukur secara objektif : Saya bekerja dalam kelompok perusahaan besar. Jika Anda tidak bisa mengukurnya secara objektif, Anda tidak bisa meminta pertanggungjawaban orang atau membuatnya lebih baik. Pengukuran subyektif tidak terjadi atau tidak terjadi secara konsisten.

Saya melihat metrik kode VS2010 , tapi saya ingin tahu apakah ada yang punya rekomendasi lain.

nlawalker
sumber
@ Anon - Saya setuju, tapi setidaknya itu akan memberi saya tempat untuk memulai. Saat ini tidak ada apa-apa; bahkan tidak harus di-gamed.
nlawalker
1
Saya benar-benar tidak melihat bagaimana Anda bisa melakukan ini tanpa ulasan kode rekan. Seseorang harus benar-benar memahami keseluruhan desain sistem (dan seseorang harus ada) untuk dapat melihat unit kode dan pergi ... hm ini dapat ditingkatkan dengan desain yang ditingkatkan atau ini adalah repisi kode atau tuan yang baik alat Anda sudah ketinggalan zaman ... Pada catatan yang sama, Anda dapat mempertahankan pedoman menyeluruh seperti, "hei ini bukan ide yang baik untuk indeks hardcode ke dalam tampilan grid, gunakan itemtemplates dan pilih kolom dengan nama sebagai gantinya". Ketika sampai pada itu, para dev hanya harus menjadi baik dan timable. Da Vinci tidak bisa mengajar kemegahan.
P.Brian.Mackey
8
Jika Anda memiliki pengembang metrik game alih-alih menulis kode yang baik, maka menambahkan metrik lebih banyak hanya akan menghasilkan metrik game itu juga, tetapi tidak akan menyelesaikan masalah . Solusinya adalah menghapus metrik sepenuhnya dan menggunakan cara lain (tinjauan kode publik, misalnya) untuk memastikan kualitas kode.
Anon.
3
"Segala sesuatu yang dapat dihitung tidak selalu berarti; segala sesuatu yang diperhitungkan tidak bisa dihitung." -Einstein
Jason Baker
@nlawalker Selain masalah yang telah dijawab penjawab, pertanyaan Anda dimuat dengan asumsi yang dapat dipertanyakan, bahwa jika pengukuran semacam itu dilakukan, orang dapat melakukan sesuatu tentangnya. Pemeliharaan rendah adalah hasil dari berbagai faktor di luar perangkat lunak itu sendiri: seberapa sulit atau terdefinisi dengan baik masalah yang coba dipecahkan oleh program, pengalaman staf, pergantian, persyaratan waktu ke pasar, perubahan ruang lingkup ... Anda tidak bisa memberi hadiah tentang mengharapkan masalah ini adalah masalah niat baik.
Arthur Havlicek

Jawaban:

7

Peringatan dengan mengukur pemeliharaan adalah bahwa Anda berusaha untuk memprediksi masa depan. Cakupan kode, jumlah bug, LOC, kompleksitas cyclomatic semua berurusan dengan saat ini .

Kenyataannya adalah bahwa kecuali Anda memiliki bukti konkret bahwa kode tersebut tidak dapat dipelihara sebagaimana mestinya ... yaitu ... memperbaiki bug yang disebabkan N jumlah jam waktu yang tidak diperlukan karena kode yang tidak dapat dikelola; kemudian memiliki kaki untuk berdiri akan sulit secara inheren. Dalam contoh ini bisa jadi disebabkan oleh fakta bahwa metodologi yang terlalu rumit digunakan ketika sesuatu yang lebih sederhana sudah mencukupi. Menuju ke area di mana Anda mencoba mengukur metodologi, paradigma, dan praktik terbaik menjadi semakin sulit dengan sedikit atau tanpa keuntungan jangka panjang.

Turun jalan ini sayangnya jalan ke mana-mana. Berfokuslah pada pengungkapan masalah root yang memiliki kelebihan substansial dan tidak terikat pada perasaan pribadi tentang suatu masalah seperti kurangnya konvensi penamaan di seluruh basis kode dan menemukan cara untuk mengukur keberhasilan dan kegagalan di sekitar masalah root tersebut. Ini kemudian akan memungkinkan Anda untuk mulai menyusun satu set blok bangunan dari mana Anda kemudian dapat mulai merumuskan solusi di sekitar.

Aaron McIver
sumber
7

Nah, ukuran yang saya gunakan, atau suka pikir saya gunakan, adalah ini:

Untuk setiap persyaratan fungsional independen, tunggal, satu baris, take-it-or-leave-it, snapshot basis kode sebelum mengimplementasikannya. Kemudian implementasikan, termasuk menemukan dan memperbaiki bug yang diperkenalkan dalam proses. Kemudian jalankan diffantara basis kode sebelum dan sesudah. The diffakan menunjukkan daftar semua sisipan, penghapusan, dan modifikasi yang dilaksanakan perubahan. (Seperti menyisipkan 10 baris kode berturut-turut adalah satu perubahan.) Berapa banyak perubahan yang ada? Semakin kecil angka itu, biasanya, semakin mudah dipelihara kode tersebut.

Saya menyebutnya redundansi kode sumber, karena itu seperti redundansi kode koreksi kesalahan. Informasi itu terkandung dalam 1 chunk, tetapi dikodekan sebagai N chunks, yang semuanya harus dilakukan bersama, agar konsisten.

Saya pikir ini adalah ide di balik KERING, tetapi sedikit lebih umum. Alasan mengapa perhitungan itu rendah adalah, jika diperlukan N perubahan untuk menerapkan persyaratan yang khas, dan sebagai programmer yang keliru, Anda hanya mendapatkan N-1 atau N-2 yang dilakukan dengan benar pada awalnya, Anda telah memasukkan 1 atau 2 bug. Di atas upaya pemrograman O (N), bug-bug itu harus ditemukan, ditemukan, dan diperbaiki. Itu sebabnya N kecil itu baik.

Maintainable tidak harus berarti dapat dibaca, untuk seorang programmer yang belum belajar bagaimana kode itu bekerja. Mengoptimalkan N mungkin perlu melakukan beberapa hal yang menciptakan kurva belajar untuk programmer. Ini sebuah contoh. Satu hal yang membantu adalah jika programmer mencoba mengantisipasi perubahan di masa depan dan meninggalkan petunjuk arah dalam komentar program.

Saya pikir ketika N berkurang cukup jauh (optimal adalah 1) kode sumber lebih mirip dengan domain-bahasa spesifik (DSL). Program tidak begitu "menyelesaikan" masalah karena "menyatakan" masalah, karena idealnya setiap persyaratan hanya disajikan kembali sebagai satu bagian kode.

Sayangnya, saya tidak melihat orang belajar bagaimana melakukan ini sangat banyak. Mereka tampaknya berpikir bahwa kata benda mental harus menjadi kelas, dan kata kerja menjadi metode, dan yang harus mereka lakukan hanyalah memutar engkol. Itu menghasilkan kode dengan N 30 atau lebih, dalam pengalaman saya.

Mike Dunlavey
sumber
Bukankah ini membuat asumsi yang sangat besar - bahwa semua persyaratan fungsional kira-kira berukuran sama? Dan bukankah metrik ini mengecilkan pemisahan tanggung jawab? Saya perlu menerapkan fitur horizontal; kode yang paling "dapat dipelihara" oleh karena itu penulisan ulang hampir total dari suatu program yang seluruhnya terkandung dalam satu metode monolitik.
Aaronaught
@Aaronaught: Saya tidak tahu seberapa besar itu, tetapi di grup kami, kami mengerjakan daftar persyaratan / fitur, beberapa saling tergantung, beberapa tidak. Masing-masing memiliki deskripsi yang relatif singkat. Jika dibutuhkan penulisan ulang besar, tentu saya telah melihat / melakukan itu, tetapi ia mengatakan kepada saya mungkin ada cara yang lebih baik untuk mengatur kode. Ini adalah contoh kanonik saya. Saya tidak mengatakan itu mudah dipelajari, tetapi sekali dipelajari itu menghemat sejumlah besar upaya yang terukur, membuat perubahan dilakukan dengan cepat tanpa kesalahan.
Mike Dunlavey
5

Maintainability sebenarnya tidak bisa diukur. Ini adalah pandangan subjektif dari seorang individu berdasarkan pengalaman dan kesukaannya.

Untuk memberi sepotong kode muncul dengan ide desain yang sempurna .

Kemudian untuk setiap penyimpangan kode nyata dari yang sempurna mengurangi nilai 100 dengan beberapa angka. Apa yang sebenarnya tergantung pada konsekuensi dari pendekatan yang tidak sempurna yang dipilih.

Sebuah contoh:

Sepotong kode membaca dan mengimpor beberapa format data dan mungkin menampilkan pesan kesalahan jika ada sesuatu yang salah.

Solusi yang sempurna (100) akan menyimpan pesan kesalahan di satu tempat umum. Jika solusi Anda meminta mereka membuat kode keras sebagai konstanta string langsung dalam kode, Anda ambil, katakan 15 off. Jadi indeks perawatan Anda menjadi 85.


sumber
4

Salah satu hasil dari kode yang sulit dipelihara adalah bahwa Anda butuh waktu lebih lama ("rata-rata") untuk memperbaiki bug. Jadi, sekilas satu metrik akan muncul sebagai waktu yang diperlukan untuk memperbaiki bug dari saat bug itu ditetapkan (yaitu perbaikan dimulai) hingga saat "siap untuk diuji".

Sekarang, ini hanya akan benar-benar berfungsi setelah Anda memperbaiki sejumlah bug untuk mendapatkan waktu "rata-rata" (apa pun artinya). Anda tidak dapat menggunakan angka tersebut untuk bug tertentu karena sulitnya melacak tidak hanya tergantung pada "pemeliharaan" kode.

Tentu saja, ketika Anda memperbaiki lebih banyak bug kode menjadi "lebih mudah" untuk dipertahankan karena Anda membuatnya lebih baik (atau setidaknya Anda seharusnya) dan Anda menjadi lebih akrab dengan kode tersebut. Melawan itu adalah fakta bahwa bug akan cenderung lebih jelas dan karenanya lebih sulit untuk dilacak.

Ini juga menderita masalah bahwa jika orang akan cenderung untuk mempercepat perbaikan bug untuk mendapatkan skor yang lebih rendah sehingga menyebabkan bug baru atau tidak memperbaiki dengan benar bug yang ada yang mengarah ke lebih banyak pekerjaan dan bahkan mungkin kode yang lebih buruk.

ChrisF
sumber
2

Saya menemukan Metrik Kode Visual Studio cukup baik untuk memberikan metrik "perawatan" yang cepat. 5 metrik utama ditangkap:

  • Kompleksitas Siklomatik
  • Tingkatan Warisan
  • Couling kelas
  • Lines of Code (per metode, per kelas, per proyek, apa pun, tergantung pada tingkat roll-up Anda)

Indeks Maintainability adalah yang saya temukan berguna. Ini adalah indeks komposit, berdasarkan pada:

  1. Total Ukuran (Garis Kode)
  2. # Kelas atau File
  3. # Metode
  4. Kompleksitas Siklomatik di atas 20 (atau 10 - dapat dikonfigurasi, 10 adalah pilihan saya)
  5. Duplikasi

Kadang-kadang saya akan melihat metode saya dengan Indeks Maintainability rendah (rendah = buruk untuk yang satu ini). Hampir tanpa gagal, metode dalam proyek saya dengan Indeks Maintainability terendah adalah yang paling membutuhkan penulisan ulang dan yang paling sulit dibaca (atau dipertahankan).

Lihat buku putih untuk informasi lebih lanjut tentang perhitungan.

Marcie
sumber
1

Dua yang akan bermakna adalah kompleksitas siklomatik dan kopling kelas. Anda tidak dapat menghilangkan kerumitan, yang dapat Anda lakukan hanyalah mempartisi menjadi beberapa bagian yang dapat dikelola. 2 langkah ini harus memberi Anda gambaran tentang di mana kode yang sulit dipelihara dapat ditemukan, atau setidaknya di mana mencari yang paling sulit.

Kompleksitas siklus adalah ukuran dari berapa banyak jalur yang ada dalam kode. Setiap jalur harus diuji (tetapi mungkin tidak). Sesuatu dengan kompleksitas di atas sekitar 20 harus dipecah menjadi modul yang lebih kecil. Modul dengan kompleksitas cycomatic 20 (satu dapat menduplikasi ini dengan 20 if then elseblok berturut-turut ) akan memiliki batas atas 2 ^ 20 jalur untuk diuji.

Kopling kelas adalah ukuran seberapa ketat ikatan kelas. Contoh beberapa kode buruk yang saya kerjakan di perusahaan saya sebelumnya mencakup komponen "lapisan data" dengan sekitar 30 item dalam konstruktor. Orang yang sebagian besar "bertanggung jawab" untuk komponen itu terus menambahkan parameter lapisan bisnis dan UI ke konstruktor / panggilan terbuka sampai itu adalah bola lumpur yang sangat besar. Jika ingatanku benar, ada sekitar 15 panggilan baru / terbuka yang berbeda (beberapa tidak lagi digunakan), semua dengan set parameter yang sedikit berbeda. Kami melembagakan ulasan kode untuk tujuan mencegahnya melakukan lebih banyak hal seperti ini - dan untuk menghindari membuatnya tampak seperti kami memilihnya, kami meninjau kode semua orang di tim, jadi kami menghabiskan setengah hari untuk 4-6 orang setiap hari karena kita tidak

Tangurena
sumber
2
Jujur saja, memiliki ulasan kode untuk semua orang bukanlah hal yang buruk. Anda mungkin merasa seperti membuang-buang waktu, tetapi kecuali jika semua orang menggunakannya sebagai alasan untuk mengendur, Anda harus mendapatkan wawasan yang berharga dari mereka.
Anon.
1

Pada intinya, rawatan hanya dapat diukur setelah diperlukan, bukan sebelumnya . Artinya, Anda hanya bisa tahu, apakah sepotong kode dapat dipertahankan, ketika Anda harus memeliharanya.

Relatif jelas untuk mengukur betapa mudahnya mengadaptasi sepotong kode untuk mengubah persyaratan. Hampir tidak mungkin mengukur sebelumnya, bagaimana hal itu akan menanggapi perubahan dalam persyaratan. Ini berarti, Anda harus memprediksi perubahan persyaratan. Dan jika Anda bisa melakukan itu, Anda harus mendapatkan harga yang mahal;)

Satu-satunya hal yang dapat Anda lakukan, adalah menyetujui dengan tim Anda, pada seperangkat aturan konkret (seperti prinsip SOLID), yang menurut Anda semua pada umumnya meningkatkan pemeliharaan.
Jika prinsipnya dipilih dengan baik (saya pikir menggunakan SOLID akan menjadi pilihan yang baik untuk memulai), Anda dapat dengan jelas menunjukkan bahwa mereka dilanggar dan meminta pertanggungjawaban penulis atas hal itu.
Anda akan mengalami waktu yang sangat sulit, mencoba untuk mempromosikan ukuran absolut untuk pemeliharaan, sambil secara bertahap meyakinkan tim Anda untuk tetap berpegang pada seperangkat prinsip yang telah disepakati dan realistis.

back2dos
sumber
1

sejumlah besar hutang teknis yang tidak pernah benar-benar ditangani

Bagaimana dengan utang teknis yang "disusul oleh peristiwa"?

Saya menulis kode jelek dan bergegas ke produksi.

Anda mengamati - dengan benar - bahwa itu tidak dapat dipertahankan.

Kode itu, bagaimanapun, adalah babak terakhir fitur untuk lini produk yang akan dinonaktifkan karena konteks hukum telah berubah dan lini produk tidak memiliki masa depan.

"Hutang teknis" dihilangkan dengan perubahan legislatif yang menjadikannya usang.

Metrik "rawatan" berubah dari "buruk" menjadi "tidak relevan" karena pertimbangan luar.

Bagaimana itu bisa diukur?

S.Lott
sumber
"Dalam seratus tahun kita semua akan mati dan semua ini tidak penting. Agaknya menempatkan segala sesuatu dalam perspektif, bukan?" Jika ada sesuatu yang tidak relevan, respons inilah yang bukan jawaban untuk pertanyaan itu.
Martin Maat
0

Hal terbaik berikutnya untuk tinjauan kode rekan adalah untuk membuat arsitektur yang bisa diterapkan sebelum meng-coding unit atau produk. Red-green-refactor adalah cara yang cukup rapi untuk melakukannya. Suruh seorang pria Sr mengumpulkan antarmuka yang bisa diterapkan dan membagikan pekerjaan itu. Semua orang dapat mengambil potongan teka-teki mereka dan menghijaukan jalan menuju kemenangan. Setelah ini, tinjauan dan refactor kode rekan akan dilakukan. Ini bekerja sangat sangat baik pada produk utama masa lalu yang saya kerjakan.

P.Brian.Mackey
sumber
0

Daftar pertanyaan

Bagaimana dengan membuat kuesioner anonim untuk para pengembang, untuk mengisi sebulan sekali atau lebih? Pertanyaannya akan seperti:

  • Berapa banyak waktu Anda bulan lalu yang Anda habiskan untuk proyek X (kurang-lebih) [0% ... 100%]
  • Bagaimana Anda menilai status basis kode dalam hal rawatan [benar-benar buruk, buruk, netral, oke, bagus, sangat bagus].
  • Seberapa kompleks Anda akan menilai basis kode dibandingkan dengan kompleksitas proyek [terlalu rumit, tepat, terlalu sederhana].
  • Seberapa sering Anda merasa di mana Anda terhambat dalam menyelesaikan tugas Anda karena kompleksitas basis kode yang berlebihan? [tidak sama sekali, sesekali, sering, terus-menerus].

(Jangan ragu untuk menambahkan pertanyaan tambahan yang menurut Anda akan berguna dalam mengukur rawatan di komentar dan saya akan menambahkannya.)

Bjarke Freund-Hansen
sumber
0

Saya dapat memikirkan dua cara untuk melihat kemampuan pemeliharaan (saya yakin ada lebih banyak orang yang bisa menghasilkan definisi yang baik.

Modifikasi tanpa pemahaman.

Dapatkah seorang pemecah masalah masuk ke dalam kode dan memperbaiki masalah tanpa perlu memahami cara kerja keseluruhan sistem.

Ini dapat dicapai dengan memberikan tes unit komprehensif (uji regresi). Anda harus dapat memeriksa bahwa setiap perubahan pada sistem tidak mengubah cara sistem berperilaku dengan input barang tertentu.

Dalam situasi ini seorang pemecah masalah harus dapat masuk dan memperbaiki bug (sederhana) dengan hanya sedikit pengetahuan tentang sistem. Jika perbaikan berhasil maka tidak ada tes regresi yang gagal. Jika ada tes regresi gagal maka Anda harus pindah ke tahap 2.

maintainabilty1 = K1 . (Code Coverage)/(Coupling of Code) * (Complexity of API)

Modifikasi dengan pemahaman.

Jika perbaikan bug menjadi tidak sepele dan Anda perlu memahami sistemnya. Lalu seperti apa dokumentasi sistem itu. Kami tidak berbicara dokumentasi API eksternal (mereka relatif tidak berguna). Yang perlu kita pahami adalah bagaimana sistem bekerja di mana trik pintar (baca retas) digunakan dalam implementasi, dll.

Tetapi dokumentasi tidak cukup kode harus jelas dan dapat dimengerti. Untuk mengukur kemampuan memahami suatu kode kita bisa menggunakan sedikit trik. Setelah pengembang menyelesaikan pengkodean, beri dia waktu sebulan untuk mengerjakan sesuatu yang lain. Kemudian minta mereka untuk kembali dan mendokumentasikan sistem sampai batas yang bisa dipahami oleh dermaga sekarang. Jika kode ini relatif mudah dimengerti maka harus cepat. Jika ditulis dengan buruk, mereka akan membutuhkan waktu lebih lama untuk mengerjakan apa yang mereka buat dan menulis dokumentasi.

Jadi mungkin kita bisa menemukan beberapa ukuran ini:

maintainability2 = K2 . (Size of doc)/(Time to write doc)
Martin York
sumber
0

Saya sering menemukan bahwa solusi "setara terpendek" cenderung paling dapat dipertahankan.

Di sini, yang terpendek berarti operasi yang paling sedikit (bukan garis). Dan yang setara berarti bahwa solusi yang lebih pendek seharusnya tidak memiliki kompleksitas ruang atau waktu yang lebih buruk daripada solusi sebelumnya.

Ini berarti semua pola pengulangan yang serupa secara logis harus diekstraksi ke abstraksi yang sesuai: Blok kode serupa? Ekstrak ke berfungsi. Variabel yang tampaknya terjadi bersama? Ekstrak mereka ke dalam struct / kelas. Kelas yang anggotanya berbeda hanya berdasarkan jenis? Anda membutuhkan obat generik. Anda tampaknya menghitung ulang hal yang sama di banyak tempat? Hitung di awal dan simpan nilai dalam variabel. Melakukan ini akan menghasilkan kode yang lebih pendek. Itulah prinsip KERING pada dasarnya.

Kami juga dapat menyetujui bahwa abstraksi yang tidak digunakan harus dihapus: kelas, fungsi yang tidak lagi diperlukan adalah kode mati, sehingga harus dihapus. Kontrol versi akan mengingat jika kita perlu mengaktifkannya kembali.

Apa yang sering diperdebatkan adalah abstraksi yang direferensikan hanya sekali: fungsi non-callback yang dipanggil hanya sekali tanpa alasan untuk dipanggil lebih dari sekali. Sebuah generik yang dipakai hanya menggunakan satu jenis, dan tidak ada alasan itu akan pernah dipakai dengan jenis lain. Antarmuka yang diimplementasikan hanya sekali dan tidak ada alasan nyata bahwa itu akan pernah dilaksanakan oleh kelas lain dan seterusnya. Pendapat saya bahwa hal-hal ini tidak perlu dan harus dihapus, itu pada dasarnya adalah prinsip YAGNI.

Jadi harus ada alat yang bisa mengenali pengulangan kode, tapi saya pikir itu adalah masalah yang mirip dengan menemukan kompresi yang optimal, yang merupakan masalah kompleksitas Kolmogorov yang tidak dapat diputuskan. Tetapi di ujung yang lain abstraksi yang tidak digunakan dan digunakan mudah dikenali berdasarkan jumlah referensi: cek untuk itu bisa otomatis.

Calmarius
sumber
0

Semuanya subyektif dan pengukuran apa pun berdasarkan kode itu sendiri pada akhirnya tidak relevan. Pada akhirnya itu tergantung pada kemampuan Anda untuk memenuhi tuntutan. Bisakah Anda masih memberikan fitur yang diminta dan jika Anda bisa, seberapa sering perubahan itu akan kembali kepada Anda karena ada sesuatu yang belum benar dan seberapa serius masalah itu?

Saya hanya (kembali) mendefinisikan rawatan tetapi masih subyektif. Di sisi lain, itu mungkin tidak terlalu penting. Kami hanya perlu memuaskan pelanggan kami dan menikmatinya, itulah yang kami tuju.

Tampaknya Anda merasa harus membuktikan kepada atasan atau rekan kerja bahwa ada sesuatu yang perlu dilakukan untuk meningkatkan status basis kode. Saya berpendapat itu harus cukup bagi Anda untuk mengatakan Anda frustrasi oleh kenyataan bahwa untuk setiap hal kecil Anda harus mengubah atau menambahkan Anda harus memperbaiki atau menangani sekitar 10 masalah lain yang bisa dihindari. Kemudian beri nama daerah yang terkenal jahat dan buat kasus untuk membalikkannya. Jika itu tidak meningkatkan dukungan di tim Anda, Anda mungkin lebih baik di tempat lain. Jika orang-orang di sekitar Anda tidak peduli, membuktikan maksud Anda tidak akan mengubah pikiran mereka.

Martin Maat
sumber