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.
sumber
Jawaban:
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.
sumber
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
diff
antara basis kode sebelum dan sesudah. Thediff
akan 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.
sumber
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
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.
sumber
Saya menemukan Metrik Kode Visual Studio cukup baik untuk memberikan metrik "perawatan" yang cepat. 5 metrik utama ditangkap:
Indeks Maintainability adalah yang saya temukan berguna. Ini adalah indeks komposit, berdasarkan pada:
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.
sumber
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 else
blok 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
sumber
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.
sumber
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?
sumber
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.
sumber
Daftar pertanyaan
Bagaimana dengan membuat kuesioner anonim untuk para pengembang, untuk mengisi sebulan sekali atau lebih? Pertanyaannya akan seperti:
(Jangan ragu untuk menambahkan pertanyaan tambahan yang menurut Anda akan berguna dalam mengukur rawatan di komentar dan saya akan menambahkannya.)
sumber
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.
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:
sumber
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.
sumber
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.
sumber