Come posso definire e misurare la semplicità nel codice?

13

Nella mia precedente domanda ci sono molte risposte su semplicità relativa alla leggibilità questo mi ha aiutato a vedere la mia definizione e comprensione della semplicità nel codice era, molto probabilmente, errata.

Come posso definire la semplicità nel codice? Quali misurazioni e metriche del software sono disponibili per misurare la semplicità del codice?

    
posta Richard 06.12.2011 - 15:46
fonte

3 risposte

16

Le metriche più comuni per misurare la complessità (o semplicità, se si prende la semplicità per essere l'opposto della complessità) sono La complessità ciclopica di McCabe e le metriche di complessità di Halstead .

La complessità ciclomatica misura il numero di percorsi distinti attraverso una determinata unità, di solito un metodo o una funzione, sebbene possa anche essere calcolata su una classe. Con l'aumento del numero di percorsi, diventa più difficile ricordare il flusso di dati attraverso un determinato modulo, che è correlato al concetto di funzionante la memoria . L'elevata complessità ciclomatica tende ad indicare difficoltà nella capacità di testare un modulo - sono necessari più casi di test per coprire i vari percorsi attraverso il sistema. Ci sono stati anche studi che hanno collegato la complessità ciclomatica ad alti tassi di difetti. Tipicamente, una complessità ciclomatica di 10 indica che un'unità dovrebbe essere rivista e possibilmente refactored.

Le misure di complessità di Halstead utilizzano gli input di operatori e operandi totali e distinti per calcolare il volume, la difficoltà e lo sforzo di un pezzo di codice. Difficoltà, che è il (numero di operatori unici / 2) * (numero totale di operandi / numero di operandi univoci), è legato alla capacità di leggere e comprendere il codice per attività come l'apprendimento del sistema o l'esecuzione di una revisione del codice. Di nuovo, puoi contare su un livello di sistema, un livello di classe o un metodo / livello di funzione. Ci sono alcuni post sul calcolo di queste misure qui e qui .

Il semplice conteggio delle righe di codice può anche darti un'idea di complessità. Più righe di codice significa che c'è più da leggere e capire in un modulo. Sarei riluttante a usare questo come misura indipendente. Invece, lo userei con altre misurazioni, come il numero di difetti in un dato modulo per ottenere la densità dei difetti. Un'alta densità di difetti potrebbe indicare problemi nella scrittura di test e nell'esecuzione di revisioni del codice, che possono essere o non essere causati da codice complesso.

Fan-in e fan-out sono altre due metriche, correlate al flusso di dati. Come definito qui , fan in è la somma delle procedure chiamate, i parametri letti e le variabili globali lette e fan out è la somma delle procedure che chiamano una determinata procedura, i parametri scritti (esposti agli utenti esterni, passati per riferimento) e le variabili globali scritte in. Ancora una volta, un alto fan-in e fan-out potrebbe essere indicativo di un modulo che potrebbe essere difficile da capire.

In paradigmi specifici, potrebbero esserci altre misure o metriche che sono anche utili. Ad esempio, nel mondo orientato agli oggetti, l'accoppiamento di monitoraggio (desiderio basso), coesione (desiderio alto) e profondità dell'ereditarietà (desiderio basso) può essere utilizzato per valutare quanto semplice o complicato sia un sistema.

Naturalmente, è importante rendersi conto che un sacco di misure e metriche sono semplicemente degli indicatori. Devi usare il tuo giudizio per determinare se è necessario un refactoring per aumentare la semplicità o se non vale la pena di farlo. È possibile effettuare misurazioni, calcolare le metriche e conoscere il proprio codice, ma non si desidera progettare il sistema in base ai numeri. In definitiva, fai ciò che ha senso.

    
risposta data 06.12.2011 - 16:59
fonte
7

Invece di considerare una modalità formale di definizione della semplicità, vorrei piuttosto definire la semplicità come un attributo della qualità della scrittura del codice.

Non sto mettendo un po 'di semplicità, ma quando chiami qualcosa di semplice o no.

1. Attraversamento codice:
Quanto è facile navigare attraverso il codice? È facile individuare dove vengono scritte le funzioni API? È facile capire i flussi di chiamate, ad esempio quali metodi chiamano gli altri (e perché) - ci sono macchine con stato buono implementate o algoritmi chiaramente identificati?

Quando il codice attraversa è facile, il codice è semplice da seguire.

2. Naming
Mentre altri standard di codifica aiutano a rendere il codice più pulito: la cosa più importante è la denominazione di classi / istanze-oggetto / Variabili / metodi. usa nomi chiari e non ambigui ha chiaramente un grande impatto sulla Semplicità del codice. Quando è difficile identificare un nome semplice, è un segno che potresti voler ripensare che l'idea è quella variabile / metodo.

3. Interpretazione e riferimenti
Ciascuno dei tuoi metodi ha un chiaro ruolo da svolgere. Ogni variabile / attributo è facile da determinare il ruolo che stanno giocando? Quando un pezzo di codice fa qualcosa che implica assunzioni o influenza un insieme di variabili non correlate, può diventare un incubo di manutenzione.

4. Dipendenza o accoppiamento
È difficile giudicare solo guardando il codice, ma diventa molto evidente se qualcuno cerca di correggere i bug. Quando alcune altre cose cambiano in qualche altro oggetto, l'operazione qui cambia? Questi cambiamenti sono ovvi? Hai bisogno di cambiare l'API così spesso per sistemare le cose. Questi suggeriscono che le relazioni intermodule non sono semplici

5. Input utente o applicazioni
Infine, quanto sono semplici gli input o le applicazioni dell'utente accettati sull'API / sull'interfaccia utente? Quando più utenti / applicazioni possibili (per scopi diversi) devono darti - sono ovvi? Ci sono stati / dettagli che non sono correlati all'astrazione più alta, ma continuano a tornare indietro all'interfaccia?

Una semplice domanda che vorrei in genere è la seguente: se invece di un programma, se avessi chiesto che la stessa funzione fosse eseguita da un essere umano, avrei riempito queste informazioni su un modulo cartaceo ? In caso contrario, non sono semplice abbastanza qui.

Non dirò che questa lista è esaustiva, ma credo che i criteri siano la facilità o la difficoltà di usare e modificare il software. È semplice

    
risposta data 06.12.2011 - 17:45
fonte
0

Non sono a conoscenza di alcuna metrica esistente valida per la semplicità del codice (non significa che non esistano, solo che non ne conosco). Potrei proporne alcuni, forse alcuni aiuteranno:

  • Semplicità delle funzionalità del linguaggio utilizzate: se la lingua ha caratteristiche che potrebbero essere considerate "avanzate" e "semplici", è possibile contare il numero di occorrenze delle funzionalità avanzate. Il modo in cui definisci "avanzato" potrebbe essere un po 'più soggettivo. Suppongo che alcuni potrebbero dire che questo è anche come misurare la "furbizia" di un programma. Un esempio comune: alcuni potrebbero dire che l'operatore ?: dovrebbe essere una funzione "avanzata", altri potrebbero non essere d'accordo. Non so quanto sarebbe facile scrivere uno strumento in grado di verificarlo.

  • Semplicità dei costrutti all'interno del programma: puoi misurare il numero di parametri che una funzione accetterà. Se hai > n % di tutte le funzioni con > m , puoi scegliere di contenerlo come non semplice, a seconda di come definisci n e m ( forse n = 3 e m = 6?). Penso che ci siano alcuni strumenti di analisi statica in grado di misurarlo - penso che JTest abbia semplicemente misurato le funzioni con > Parametri m .

  • Potresti provare a contare il numero di loop nidificati o strutture di controllo. Questo penso che in realtà non sia una cattiva metrica e penso che ci sia un nome per questo (non riesco a ricordare in cima alla mia testa). Ancora una volta, penso che ci siano strumenti (di nuovo, come JTest) in grado di misurare questo, in una certa misura.

  • Potresti provare a misurare la "refactability". Se il tuo codice contiene molte parti di codice che potrebbe essere refactored ma non , forse ciò potrebbe non essere semplice. Ricordo anche dal momento in cui ho lavorato con JTest che ha provato a misurare anche questo, ma ricordo che non ero d'accordo con lui in questo caso, quindi YMMV.

  • Potresti provare a misurare il numero di livelli tra diverse parti del tuo sistema. Ad esempio: quanti pezzi diversi di codice toccheranno i dati provenienti da un modulo Web prima che vengano memorizzati nel database? Potrebbe essere difficile da misurare correttamente ...

risposta data 06.12.2011 - 17:07
fonte

Leggi altre domande sui tag