Bagaimana saya bisa mendefinisikan dan mengukur kesederhanaan dalam kode?

13

Ada banyak jawaban dalam pertanyaan saya sebelumnya tentang kesederhanaan yang berkaitan dengan keterbacaan yang membantu saya melihat definisi dan pemahaman saya tentang kesederhanaan dalam kode, sangat mungkin, salah.

Bagaimana saya bisa mendefinisikan kesederhanaan dalam kode? Pengukuran dan metrik perangkat lunak apa yang tersedia untuk mengukur kesederhanaan kode?

Richard
sumber
2
@MarkTrapp Ada cara lain untuk membahas kesederhanaan kode tanpa topik dari rekayasa perangkat lunak empiris, topik yang saya tidak terlalu kenal. Misalnya, membahas kesederhanaan dalam hal kemampuan menulis tes otomatis. Keterampilan dan pengetahuan saya memungkinkan saya untuk menjawab pertanyaan ini dari sudut pandang seorang insinyur perangkat lunak empiris, sementara yang lain dapat menjawab dari perspektif alternatif. Menambahkan pernyataan itu ke pertanyaan membatasi jumlah jawaban yang berguna secara signifikan, menjadikannya (IMO) terlalu terlokalisasi. Jika Anda ingin menambahkannya, Anda bisa, tetapi ini adalah pertanyaan yang bagus.
Thomas Owens
2
@ThomasOwens Pertanyaan nyata memiliki jawaban , bukan ide atau pendapat. Mempersempit ruang lingkup sehingga semua orang mengartikan bagaimana menjawab pertanyaan dengan cara yang sama persis dengan apa yang dimaksud dengan Stack Exchange. Mungkin ada lebih dari satu pendekatan untuk menyelesaikan masalah, tetapi hanya ada satu masalah yang dinyatakan secara jelas.
Dalam keadaan saat ini, ada sangat sedikit jawaban untuk pertanyaan ini (jawaban saya membahas sudut pandang rekayasa perangkat lunak empiris, dengan metrik umum - mungkin ada yang lain). Tidak masuk akal untuk mengecualikan jawaban yang memberikan alternatif yang valid dari perspektif lain, yang merupakan apa kata-kata dari pertanyaan ini. Saya sepenuhnya tidak setuju dengan pengeditan ini dan pertanyaannya harus dikembalikan ke bentuk aslinya.
Thomas Owens
@ MarkTrapp Masalahnya tidak ambigu: Bagaimana cara saya menentukan kesederhanaan kode? Ada beberapa jawaban bagus. Milik saya menggunakan teknik rekayasa perangkat lunak empiris untuk mengukur kompleksitas. Yang lain mungkin menulis tes otomatis dan jika sulit untuk menulis tes yang baik, kodenya kompleks - jawaban yang benar-benar valid. Mungkin ada orang lain yang tidak saya sadari. Jika Anda perlu mengukur kerumitan / kesederhanaan basis kode, pertanyaan tersebut harus diucapkan dengan cara yang memungkinkan semua alternatif disajikan sehingga penanya dapat memilih solusi terbaik untuk kasus khususnya.
Thomas Owens

Jawaban:

16

Metrik yang paling umum untuk mengukur kompleksitas (atau kesederhanaan, jika Anda menganggap kesederhanaan sebagai kebalikan dari kompleksitas) adalah Kompleksitas Sikomatik McCabe dan Metrik Kompleksitas Halstead .

Kompleksitas siklus mengukur jumlah jalur yang berbeda melalui unit yang diberikan, biasanya metode atau fungsi, meskipun juga dapat dihitung pada kelas. Dengan meningkatnya jumlah jalur, menjadi lebih sulit untuk mengingat aliran data melalui modul yang diberikan, yang terkait dengan konsep memori kerja . Kompleksitas siklomatik yang tinggi cenderung mengindikasikan kesulitan dalam kemampuan untuk menguji suatu modul - dibutuhkan lebih banyak kasus uji untuk mencakup berbagai jalur melalui sistem. Ada juga penelitian yang mengaitkan kompleksitas siklomatik yang tinggi dengan tingkat cacat yang tinggi. Biasanya, kerumitan siklomatik 10 menunjukkan bahwa suatu unit harus ditinjau dan mungkin dire-reforasi.

Langkah-langkah kompleksitas Halstead menggunakan input dari operator dan operan total dan berbeda untuk menghitung volume, kesulitan, dan upaya sepotong kode. Kesulitan, yang merupakan (jumlah operator unik / 2) * (jumlah total operan / jumlah operan unik), terkait dengan kemampuan membaca dan memahami kode untuk tugas-tugas seperti mempelajari sistem atau melakukan tinjauan kode. Sekali lagi, Anda dapat menghitung ini pada level sistem, level kelas, atau level metode / fungsi. Ada beberapa posting tentang menghitung pengukuran ini di sini dan sini .

Hanya dengan menghitung baris kode juga dapat memberi Anda gambaran tentang kompleksitas. Semakin banyak baris kode berarti ada lebih banyak untuk dibaca dan dipahami dalam modul. Saya akan ragu untuk menggunakan ini sebagai ukuran yang berdiri sendiri. Sebagai gantinya, saya akan menggunakannya dengan pengukuran lain, seperti jumlah cacat dalam modul yang diberikan untuk mendapatkan kepadatan cacat. Kerapatan cacat yang tinggi dapat mengindikasikan masalah dalam penulisan tes dan pelaksanaan tinjauan kode, yang mungkin atau mungkin tidak disebabkan oleh kode kompleks.

Fan-in dan fan-out adalah dua metrik lainnya, terkait dengan aliran data. Seperti yang didefinisikan di sini , fan in adalah jumlah dari prosedur yang disebut, pembacaan parameter, dan variabel global read and fan out adalah jumlah dari prosedur yang memanggil prosedur yang diberikan, parameter yang ditulis (diekspos ke pengguna luar, diteruskan dengan referensi), dan variabel global yang ditulis untuk. Sekali lagi, fan-in dan fan-out yang tinggi mungkin mengindikasikan modul yang mungkin sulit untuk dipahami.

Dalam paradigma tertentu, mungkin ada tindakan atau metrik lain yang juga berguna. Sebagai contoh, di dunia berorientasi objek, pemantauan kopling (keinginan rendah), kohesi (keinginan tinggi), dan kedalaman warisan (keinginan rendah) dapat digunakan untuk menilai seberapa sederhana atau rumit suatu sistem.

Tentu saja, penting untuk menyadari bahwa banyak tindakan dan metrik hanyalah indikator. Anda perlu menggunakan penilaian Anda untuk menentukan apakah perlu refactor untuk meningkatkan kesederhanaan atau jika itu tidak sepadan dengan upaya untuk melakukannya. Anda dapat melakukan pengukuran, menghitung metrik, dan mempelajari kode Anda, tetapi Anda tidak ingin mendesain sistem Anda dengan angka. Pada akhirnya, lakukan apa yang masuk akal.

Thomas Owens
sumber
5
Saya tahu Anda menyebutkannya tetapi penting untuk menekankan bahwa kompleksitas siklomatik benar-benar hanya berguna pada tingkat fungsi / metode dan secara signifikan lebih subjektif / tidak berguna pada tingkat yang lebih tinggi.
Ryathal
Masalahnya adalah bahwa sementara langkah-langkah ini bagus sebagai panduan umum. Ada beberapa kasus di mana program "buruk" mendapat skor baik, misalnya, memiliki selusin fungsi, di mana satu fungsi dengan dua parameter lebih mencukupi, dan, sebaliknya banyak program "baik" yang merupakan solusi yang ditulis dengan baik untuk masalah yang kompleks dapat memberi skor sangat.
James Anderson
@ James, saya secara eksplisit menunjukkan hal itu. Pengukuran atau metrik apa pun perlu diambil dalam konteks sebagai indikator bahwa sesuatu harus dilihat. Dibutuhkan penilaian dari seorang insinyur untuk menentukan apakah tindakan korektif diperlukan dan apa tindakan itu. Namun, kecuali Anda secara aktif mengumpulkan data, tidak ada cara empiris untuk mengetahui potensi masalah.
Thomas Owens
7

Alih-alih melihat mode formal mendefinisikan kesederhanaan, saya lebih suka mendefinisikan kesederhanaan sebagai atribut kualitas penulisan kode.

Saya tidak menaruh sedikit kesederhanaan tetapi kapan Anda menyebut sesuatu yang sederhana atau tidak.

1. Kode Traversal:
Seberapa mudah untuk menavigasi kode? Apakah mudah dikenali dari mana fungsi API ditulis? Apakah mudah untuk memahami aliran panggilan, misalnya metode mana yang memanggil orang lain (dan mengapa) - apakah ada mesin negara yang baik diimplementasikan atau algoritma yang diidentifikasi dengan bersih?

Ketika traversal kode mudah, kode mudah diikuti.

2. Penamaan
Sementara standar pengkodean lainnya membantu membuat kode terlihat lebih bersih - yang paling penting adalah penamaan kelas / objek-instance / Variabel / metode. The Penggunaan nama jelas dan tidak ambigu jelas memiliki dampak yang besar pada Kesederhanaan kode. Ketika sulit untuk mengidentifikasi nama yang sederhana, itu adalah tanda bahwa Anda mungkin ingin memikirkan kembali idenya sebagai variabel / metode tersebut.

3. Interpretasi dan referensi
Apakah setiap metode Anda memiliki peran yang jelas untuk dimainkan. Apakah setiap variabel / atribut mudah untuk menentukan peran yang mereka mainkan? Ketika sepotong kode melakukan sesuatu yang menyiratkan asumsi atau mempengaruhi set variabel yang tidak terkait, bisa menjadi mimpi buruk pemeliharaan.

4. Ketergantungan atau penggabungan
Ini sulit untuk dinilai hanya dengan melihat kode, tetapi menjadi sangat jelas jika seseorang mencoba untuk memperbaiki bug Anda. Ketika beberapa hal lain berubah di beberapa objek lain, apakah operasi di sini berubah? Apakah perubahan itu jelas? Apakah Anda perlu mengubah API begitu sering untuk mengakomodasi hal-hal. Ini menunjukkan bahwa hubungan antar moda tidak sederhana

5. Input Pengguna atau Aplikasi
Akhirnya seberapa sederhana input atau aplikasi pengguna diterima di API / UI? Ketika beberapa kemungkinan Pengguna / Aplikasi (untuk tujuan yang berbeda) perlu memberi Anda - apakah sudah jelas? Apakah ada status / detail yang tidak terkait dengan abstraksi yang lebih tinggi tetapi masih berjalan mundur antarmuka?

Pertanyaan sederhana yang biasanya saya tanyakan adalah sebagai berikut: Jika alih-alih sebuah program, jika saya akan meminta fungsi yang sama dilakukan oleh manusia, akankah saya mengisi informasi ini pada formulir kertas ? Jika tidak, saya tidak cukup sederhana di sini.

Saya tidak akan mengatakan daftar ini lengkap, tetapi saya tetapi saya kira kriteria adalah seberapa mudah atau sulit untuk menggunakan dan memodifikasi perangkat lunak. Itu sederhana.

Dipan Mehta
sumber
1
Dia meminta pengukuran dan metrik. Ini subyektif, jadi saya tidak berpikir mereka sangat tepat.
psr
@psr saya setuju dengan Anda. Itu juga sangat jelas dari jawaban dari jawaban Thomas. Namun, ia menyebutkan kesederhanaan terkait dengan keterbacaan . Jawaban Thomas berkaitan dengan kompleksitas Siklomatik - ini memberitahu Anda betapa rumitnya untuk menguji kode dan bukan seberapa kompleks kode dalam hal keterbacaan dan mungkin untuk memperpanjang pemeliharaan . Ini adalah dua konsep yang sangat berbeda. Itulah sebabnya saya menulis jawaban ini untuk menempatkan kontradiksi yang nyata. Sayangnya setahu saya tidak ada metrik yang merujuk pada kesederhanaan kode dalam hal keterbacaan.
Dipan Mehta
"gunakan nama yang tidak mungkin disalahpahami" - IMHO ini terlalu tinggi, untuk tujuan yang tidak realistis dan tidak mungkin. Saya lebih suka tidak mencoba menjadi begitu pasti dan hanya mengatakan "menggunakan nama yang jelas dan tidak ambigu".
Péter Török
@ PéterTörök saya setuju. Saya pikir biasanya, di banyak organisasi, aturan aturan penamaan yang sangat jelas dan masih ada kebingungan tentang intensitas variabel tertentu tetap ada. Jadi penekanannya adalah mengatakan bahwa kejelasan tujuan sama dengan kesederhanaan yang bertentangan dengan aturan formal. Mungkin saya berlebihan dalam cara saya menggambarkan. Terima kasih.
Dipan Mehta
@Dipan Kompleksitas siklis terkait dengan keterbacaan kode, melalui memori yang bekerja. Kode dengan kompleksitas siklomatik tinggi (atau bahkan hanya kedalaman blok tinggi) sulit untuk disimpan dalam memori kerja, karena itu lebih sulit untuk dibaca langsung.
Thomas Owens
0

Saya tidak mengetahui adanya metrik yang ada untuk kesederhanaan kode (itu tidak berarti mereka tidak ada - hanya saja saya tidak tahu tentang mereka). Saya bisa mengusulkan beberapa, mungkin beberapa akan membantu:

  • Kesederhanaan fitur bahasa yang digunakan: jika bahasa tersebut memiliki fitur yang mungkin dianggap "canggih" dan "sederhana" Anda dapat menghitung jumlah kemunculan fitur-fitur canggih. Bagaimana Anda mendefinisikan "lanjutan" mungkin sedikit lebih subjektif. Saya kira beberapa orang mungkin mengatakan ini juga seperti mengukur "kepintaran" suatu program. Contoh umum: beberapa mungkin mengatakan bahwa ?:operator harus menjadi fitur "lanjutan", yang lain mungkin tidak setuju. Saya tidak tahu betapa mudahnya menulis alat yang bisa menguji ini.

  • Kesederhanaan konstruk dalam program: Anda bisa mengukur jumlah parameter yang akan diterima fungsi. Jika Anda memiliki> n % dari semua fungsi dengan> parameter m , Anda dapat memilih untuk menghitungnya sebagai tidak sederhana, tergantung pada bagaimana Anda mendefinisikan n dan m (mungkin n = 3 dan m = 6?). Saya pikir ada beberapa alat analisis statis yang dapat mengukur ini - saya pikir JTest hanya mengukur fungsi dengan parameter > m .

  • Anda bisa mencoba menghitung jumlah loop bersarang atau struktur kontrol. Ini saya pikir sebenarnya bukan metrik yang buruk dan saya pikir ada nama untuk itu (tidak dapat mengingat bagian atas kepala saya). Sekali lagi, saya pikir ada alat (sekali lagi, seperti JTest) yang dapat mengukur ini, sampai taraf tertentu.

  • Anda bisa mencoba mengukur "refactorability". Jika kode Anda mengandung banyak potongan kode yang bisa dire-refored tetapi tidak , mungkin itu bisa tidak sederhana. Saya juga ingat dari waktu saya bekerja dengan JTest yang mencoba mengukur ini juga, tapi saya ingat saya tidak sering setuju dengan itu dalam kasus ini, jadi YMMV.

  • Anda dapat mencoba mengukur jumlah lapisan di antara berbagai bagian sistem Anda. Sebagai contoh: berapa banyak potongan kode yang akan menyentuh data yang berasal dari formulir web sebelum disimpan dalam database? Ini bisa menjadi rumit untuk mengukur dengan benar ...

FrustratedWithFormsDesigner
sumber
2
Saya percaya # 3 disebut kedalaman blok. Ini juga terkait dengan Kompleksitas Siklomatik jika ada struktur kontrol pengambilan keputusan yang terlibat.
Thomas Owens
Tidak ada penjelasan downvote?
FrustratedWithFormsDesigner
Tidak setuju dengan "kesederhanaan fitur bahasa". Fitur-fitur canggih ada untuk menyederhanakan kode. Dengan hanya menggunakan fitur-fitur dasar yang sederhana akan mengaburkan apa yang sebenarnya dilakukan oleh kode tersebut, hal itu pasti akan menyebabkan lapisan abstraksi yang bocor. Fitur bahasa tingkat lanjut memungkinkan untuk mengekspresikan tingkat abstraksi yang lebih tinggi, membuat kode Anda jauh lebih padat dan mudah dibaca. Semakin banyak fitur canggih yang Anda gunakan (tentu saja dengan bijak), semakin baik untuk kesederhanaan. Bandingkan saja sebuah kode di, katakanlah, Matlab (yang memang "canggih") dengan kode Fortran serupa yang dibuat dari fitur-fitur dasar saja.
SK-logic
Dan saya tidak akan setuju dengan sejumlah lapisan metrik juga. Jika Anda dapat melakukan sesuatu dalam selusin langkah sepele dan bersih atau dalam satu transformasi bengkok, lebih baik lakukan dalam beberapa langkah. Banyak lapisan sederhana dan terpisah jelas jauh lebih baik (dan lebih sederhana) daripada satu lapisan bengkok.
SK-logic
@ SK-logic: Saya kira saya seharusnya menyebut yang satu itu "kepintaran", lebih dekat dengan apa yang saya maksudkan. Saya hanya akan mengatakan bahwa hal-hal seperti ?:masalah ketika mereka bersarang 5 dalam. Sedangkan untuk lapisan, lapisan yang dipisahkan dengan bersih lebih baik daripada satu lapisan yang berbelit-belit. Tetapi 7 lapisan yang kebanyakan redundan, ketika hanya 2 atau 3 yang diperlukan adalah hal yang buruk.
FrustratedWithFormsDesigner