Input della funzione di debug rispetto agli utenti in attesa del codice per leggere la documentazione - Quanto lontano posso andare? [duplicare]

5

Potrei scrivere una quantità infinita di codice di debug per gestire i vari componenti di input per una funzione, controllare che vengano utilizzati i tipi di dati corretti, assicurarsi che le cose siano discendenti degli oggetti prototipo corretti, i dati siano all'interno di un certo valore range o set ... L'elenco potrebbe continuare all'infinito.

Ma ovviamente posso anche usare le API di commento sulla documentazione per generare una buona documentazione sull'input e sull'utilizzo attesi.

La mia domanda è: fino a che punto / approfondito dovrei andare fino al debug / controllo dell'input per gli utenti del codice, piuttosto che aspettarsi che leggano la documentazione di funtion / metodo per un uso corretto?

Potremmo dire "Dipende da chi è responsabile", ma sono interessato alle migliori pratiche per la massima efficienza.

    
posta Viziionary 22.09.2015 - 14:52
fonte

5 risposte

11

Concentrarsi sulla scrittura di codice "efficiente" senza effettivamente definire l'efficienza è una trappola in cui gli sviluppatori cadono.

L'efficienza non riduce sempre il numero di cicli della CPU necessari per eseguire un'attività. In effetti, per la maggior parte dei programmatori, nella maggior parte dei casi, ossessionare il processo di rasatura dei cicli della CPU è una completa perdita di tempo.

Dove Efficienza = minimizzazione dei cicli della CPU

La maggior parte del software aziendale contiene logica banale.

Immagina di spendere 30 minuti per radere un po 'di CPU dal tuo codice. Diciamo solo che hai avuto una buona giornata e hai rasato 2000 cicli. La tua tipica CPU a 2 GHz subirà 2 milioni di cicli al secondo, il che significa che i tuoi 2000 cicli salvati ammontano a 0,000001 secondi o 1 microsecondo salvati.

La tua applicazione dovrebbe eseguire quel codice ottimizzato 30.000.000 volte prima di interrompere il tuo investimento nel tempo.

In tutto il mio tempo nel mondo del software aziendale, non posso pensare a un'istanza in cui quell'investimento iniziale di 30 minuti sarebbe stato ripagato prima di lasciare quel ruolo per un altro lavoro.

Dove Efficienza = tempo risparmiato IN GENERALE

D'altro canto, se definisci l'efficienza in termini di tempo risparmiato in generale , allora i tuoi razzi Sky ROI.

Quindi, in questo scenario, il tempo risparmiato include (ma non è limitato a) quanto segue:

  • Il tuo tempo prova la tua API
  • Problemi di debug dell'ora di Consumer Consumer con la tua API
  • Problemi di debug in tempo con il tuo consumer API
  • Il tuo tempo di gestione chiama una API fragile e rotta (no, il consumatore non ha letto la tua documentazione)

Con questa definizione di efficienza, un po 'di programmazione difensiva fa molto. Fare in modo che la tua API fallisca presto e non riesca a gestire i dati di input errati richiede un tempo di anticipo molto ridotto e ti consente di risparmiare tempo e denaro per i tuoi clienti.

La cosa importante da ricordare è che il tempo tuo e il tempo del consumatore del tuo utente sono molto più preziosi ( leggi: costoso ) del tempo della CPU .

Altri domini

Esistono tuttavia domini in cui l'efficienza può significa minimizzare i cicli della CPU. Ma tieni presente che quei domini oggi sono sempre meno.

Due di quelli che mi vengono in mente sono la codifica per sistemi realtime e analisi dei dati ad alto volume .

TL; DR

Quindi, a meno che tu non sappia per certo che hai bisogno di radere i cicli della CPU, e un approccio migliore sarebbe il codice in modo tale da salvare te stesso e altri come molto tempo possibile. Nel mondo dell'API puoi farlo con contratti di codice chiari e programmazione difensiva.

    
risposta data 22.09.2015 - 15:44
fonte
7

Ci sono due lati del problema.

  • Come sviluppatore, devi disinfettare i tuoi input. Non fidatevi degli utenti a leggere la vostra documentazione in modo approfondito e non fidatevi degli utenti a seguire la documentazione. Per quanto riguarda la sicurezza, se si tratta di un'API pubblica e ci si aspetta che gli utenti disinfettino l'input, le cose andranno molto male molto rapidamente. Per le API non pubbliche, anche la fiducia negli input è problematica; se il tuo codice fa accadere cose brutte quando viene dato un input non valido, è il tuo codice che verrà biasimato, non quello del chiamante.

    Se l'input non è valido, genera un'eccezione.

  • Come provider API, potresti voler semplificare il lavoro dei chiamanti che potrebbero non avere familiarità con la tua API (e trovare la tua documentazione troppo difficile, poco pratica o noiosa da leggere). Un modo per semplificare la loro vita è fornire messaggi di errore espliciti. Questa è la differenza tra:

    throw new Exception("Invalid input.");
    

    che significa semplicemente RTFM e:

    throw new ArgumentOutOfRangeException("price", "The price cannot be negative.");
    

    che offre un modo conveniente per sapere esattamente cosa c'è di sbagliato nel codice del chiamante.

    Se l'input non è valido e hai tempo sufficiente per spiegare perché è non valido, fallo nell'eccezione.

    Se l'errore di input viene eseguito facilmente e si verifica spesso, concentrati su ciò per eliminare la possibilità per i chiamanti di eseguire l'errore o fornire un messaggio di errore molto dettagliato.

risposta data 22.09.2015 - 15:07
fonte
6

Ovviamente dipende dal modo in cui le cose sono fatte nella vostra organizzazione, (politica del lavoro di qualità vs. politica del lavoro rapido e sporco, presenza o assenza di una cultura del rispetto mostrata dai programmatori del middleware verso i programmatori di applicazioni, ecc.), ma in generale:

La cosa "migliore" è quella di scrivere API auto-documentanti il cui utilizzo è il più chiaro possibile con una breve panoramica dell'interfaccia, e per mai aspettarsi che i chiamanti della tua API ho memorizzato, o addirittura di aver infastidito a lungo, con la documentazione. I chiamanti della tua API lo invocheranno in modi strani esaminando gli scenari "what if". I chiamanti della tua API lo invocheranno in modi che non avresti mai nemmeno immaginato.

In genere le API dovrebbero essere a prova di proiettile e idiotproof.

E questa è una buona cosa. Perché? Perché:

Un'eccezione "Null Pointer Exception" o "Division by Zero" generata da qualche parte all'interno del tuo codice è sempre considerata come colpa tua. Quindi, per ogni singolo bug nel codice del chiamante, il bug viene comunque assegnato a te. Devi riprodurlo, devi risolverlo, devi scoprire che è colpa loro, invece, e devi convincerli che è così.

Un'eccezione "Argomento non valido" generata dal tuo codice viene sempre considerata come colpa del chiamante. Il bug report va direttamente a loro. Tranquillità.

Eccessivi argomenti tra programmatori di applicazioni e programmatori middleware in cui ognuno sta cercando di dimostrare che è colpa dell'altro sono generalmente indicativi di lavori sciatti per conto del programmatore del middleware.

Modifica:

Ho appena notato il termine "massima efficienza" nella domanda. Non è chiaro cosa intendi per efficienza. Le inefficienze nel processo di sviluppo (litigi per la cui colpa è) possono spesso sprecare enormi quantità di tempo. Ora, le inefficienze nel runtime non sono in genere un problema, perché è sempre possibile utilizzare asserzioni, che sono abilitate solo nella build di debug dell'applicazione. Tuttavia, se non si desidera utilizzare le asserzioni, le inefficienze derivanti dal controllo dei parametri codificati non sono generalmente un problema in macchine moderne, multi-core, multi-pipeline, multi-livello-cache, multi-gigaherz. Se qualcuno ha un problema, digli di comprare un hardware migliore. Questo è spesso considerato anche una best practice.

    
risposta data 22.09.2015 - 15:18
fonte
0

Come sviluppatore di un'API devi decidere e documentare quali input validi sono e devi decidere e documentare cosa fai con input non validi. È inoltre necessario decidere quali sono le cose che non funzionano e quali sono gli errori del programmatore. Ad esempio, un percorso a un file non esistente potrebbe "non funzionare", mentre un puntatore nullo o una stringa vuota come percorso potrebbe essere un "errore di programmazione". E infine, questo dovrebbe essere discusso con gli utenti dell'API (a meno che tu non abbia esperienza sufficiente per decidere senza il loro contributo).

Se possibile, rileva errori di programmazione (ovvero errori in cui ti aspetti che qualcuno cambi il loro codice) e interrompa il programma. Se possibile, rilevare altri problemi, evitare arresti anomali o fare qualcosa di male e segnalare il problema in modo che possa essere risolto o gestito dal chiamante.

La documentazione leggibile consente agli utenti di leggere la documentazione: -)

    
risposta data 22.09.2015 - 16:37
fonte
0

Per un'API pubblica, ecco le mie regole empiriche:

  • Convalida tutti gli input che possono causare un comportamento imprevisto.
  • Convalida gli input quando li vedi per la prima volta.
    • Non convalidare nuovamente gli input nelle funzioni di supporto interne.
  • Per gli input che potrebbero verosimilmente derivare dall'input dell'utente, restituire codici / messaggi di errore utili.
    • if (date < today) return err_NEED_FUTURE_DATE;
    • tieni presente che non è solo err_INVALID_DATE , che non fornisce assistenza sufficiente.
  • Per gli input che probabilmente provengono dal programmatore, alza Asserzioni / eccezioni:
    • if (buffer_size < 1) RAISE("Buffer must be at least one byte");
risposta data 22.09.2015 - 19:46
fonte

Leggi altre domande sui tag