Quanta ridondanza / robustezza dovrebbe implementare un software complesso?


12

Il focus di questa domanda: alcuni software eseguono "lavori extra" al fine di aumentare le possibilità di un risultato "eventualmente positivo / soddisfacente", nonostante uno o più errori interni nel software, che richiede tempi di esecuzione più lunghi quando si verificano tali errori. Tutto ciò avviene all'insaputa dell'utente se l'esito ha avuto esito positivo.

Definizione di software complesso:

  • Contiene codice scritto da (contribuito da) più di 10 sviluppatori nel corso della sua vita e non scritto nello stesso lasso di tempo
  • Dipende da più di 10 librerie esterne, ognuna con avvertenze
  • Un'attività software tipica (per generare un risultato desiderato dall'utente) richiede 10 o più parametri di input, in cui la maggior parte ha valori predefiniti ma sono configurabili se l'utente ha bisogno di controllo.
  • Soprattutto, un software che presenta la complessità appropriata rispetto all'attività eseguita, ovvero non inutilmente complicato .

Modificato: cos'è complesso? Si prega di vedere C'è una grande differenza tra Complesso e Complicato . (collegamento diretto)

Definizione di ridondanza / robustezza all'interno di questa domanda :
(aggiunta robustezza in base ai commenti)

  • Se un'attività software non è riuscita quando è stata utilizzata la serie di parametri corrente, provare diversi parametri.
    • Ovviamente, ci deve essere la consapevolezza che quei parametri "diversi" usano un percorso di codice diverso, probabilmente con un risultato diverso (si spera meglio).
    • A volte questi diversi percorsi di codice sono scelti in base alle osservazioni delle librerie esterne.
  • Alla fine, se l'attività effettiva eseguita è leggermente diversa dalle specifiche dell'utente, l'utente riceverà un rapporto dettagliato della discrepanza.
  • Infine, come i parametri 10 plus configurabili, anche la ridondanza e il reporting sono configurabili.

Esempio di tale software:

  • Migrazione del database
    • Database aziendale
    • Database di controllo del codice sorgente, ecc.
  • Conversione in batch tra un documento Word e un documento OpenOffice, PowerPoint e OpenOffice Draw, ecc.
  • Traduzione automatica di un intero sito Web
  • Analisi automatica di pacchetti software, come Doxygen, ma in cui l'analisi deve essere più affidabile (cioè non solo uno strumento di documentazione)
  • Comunicazione di rete, in cui i pacchetti potrebbero andare persi e sono previsti numerosi tentativi

Questa domanda è stata originariamente ispirata da Come gestisci il codice intenzionalmente errato?
ma ora è focalizzato solo su una delle cause del gonfiamento del software. Questa domanda non affronta altre cause di rigonfiamento del software, come l'aggiunta di nuove funzionalità.

Possibilmente correlato:


5
Questa non è ridondanza, questa è robustezza ...

5
La risposta non è semplicemente "quanto è necessario?"
Dean Harding,

@ Decano - assolutamente, è un requisito come un altro. Il trucco sta nel spiegarlo e le conseguenze e i costi per gli utenti, ma può essere fatto.
Jon Hopkins,

Grazie @ Thorbjørn per il feedback. Ho aggiunto robustezza al titolo e alla definizione.
rwong

Stai lontano da una vecchia base di codice, a meno che tu non abbia 5 figli da sfamare.
Giobbe

Risposte:


7

Questa è una domanda commerciale, non tecnica.

A volte sto programmando con i ricercatori o su un prototipo, quindi costruiremo qualcosa con una robustezza molto bassa. Se si rompe, lo ripariamo. Non ha senso investire in magie extra se elimineremo presto il codice.

Ma se gli utenti del tuo sistema hanno bisogno che sia robusto, dovresti costruirlo in quel modo. E dovresti renderlo robusto specificamente nei modi in cui tu e loro hanno bisogno per massimizzare il successo a lungo termine, ignorando i tipi di ridondanza / robustezza di cui non hanno bisogno.

In generale, inizio in modo approssimativo e quindi aggiungo robustezza nel tempo. Faccio spesso domande come questa parte del normale processo di pianificazione. In genere lavoro nello stile di programmazione estrema, in cui facciamo un lungo elenco di funzionalità desiderate e inserisco anche funzionalità di robustezza. Ad esempio, "Il sistema sopravvive al fallimento di ogni singola casella", si confonde con cose come "L'utente può partecipare utilizzando le credenziali di Facebook". Qualunque sia il primo caso, costruisco per primo.


5

Il software complesso in genere è ridondante come probabilmente saprai, ma ovviamente non perché è il modo migliore per farlo, ma perché gli sviluppatori tendono a "attaccare" il codice esistente piuttosto che tentare di capire in dettaglio come funziona il software.

Tuttavia, se mi chiedessi quanta ridondanza dovrebbe essere accettabile, non direi assolutamente nulla. La ridondanza è uno dei tanti effetti collaterali della complessità, l'arcnemesi della semplicità. Probabilmente, la semplicità dovrebbe fare un passo indietro se il tempo è di maggiore importanza, sebbene sottolinei che coloro che sostengono che il tempo è essenziale sono raramente quelli che si occupano effettivamente dello sviluppo del software. Di solito è il tuo project manager che ti spinge a fare il lavoro il più presto possibile in modo da poter tornare a problemi più urgenti, tuttavia è tuo dovere come programmatore sapere quando il lavoro è finito. Penso che il lavoro non sia finito fino a quando non lo avrai integrato con successo nel programma come doveva essere. Forse il programma è complicato,

Tuttavia, si dovrebbe dire che nel fare ciò, potrebbe essere necessario produrre codice ridondante. Se il progetto è già estremamente ridondante, in realtà potrebbe essere più semplice continuare lo schema ipotizzando che il tuo capo non abbia un paio di settimane da ammazzare, permettendoti di ristrutturare l'intero progetto.

Modifica: alla luce della riformulazione della domanda, aggiungerò un po 'di robustezza. A mio avviso, il controllo dei parametri dovrebbe essere eseguito solo se A) si accetta un formato molto specifico come un valore di data come stringa o B) vari parametri potenzialmente potrebbero essere in conflitto tra loro o si escludono a vicenda.

Con A), i requisiti per cui i parametri corrispondono a un formato specifico sono generalmente fondamentali per la necessità del metodo (come una conversione in una data da una stringa). Tecnicamente potrebbe ancora accadere nel tuo programma senza che sia una necessità, ma ti incoraggio vivamente ad eliminare queste possibilità e ad accettare solo i parametri che conosci rappresentano il tipo di dati che stai cercando (Accetta una data anziché una stringa se il punto non è convertire per esempio. Se è necessario eseguire anche la conversione, utilizzare un metodo di utilità per convertire la stringa prima di passarla al metodo).

Per quanto riguarda B), i parametri reciprocamente esclusivi rappresentano una struttura errata. Dovrebbero esserci due classi, una che gestisce un caso e un altro che lo gestisce in un altro modo. Tutte le operazioni comuni possono essere eseguite in un'unica classe base per evitare ridondanza.

In situazioni in cui il numero di parametri di un metodo diventa 10+, inizio a considerare un file di proprietà che contiene tutti questi parametri che molto probabilmente non cambieranno spesso. Se cambiano, è possibile salvare il valore predefinito nel file delle proprietà e aggiungere un metodo "setPropertyName ()" che consente di sovrascrivere il valore predefinito in fase di esecuzione.


4
Penso che tu abbia frainteso la domanda. Vuol dire "ridondanza" come in "non morire in fiamme quando si verifica un errore" non come in "scrivere codice duplicato". Robustezza è un termine migliore per questo, come altri hanno sottolineato.
Adam Lear

la ridondanza è una cosa positiva in compiti cruciali. il corpo umano è l'esempio perfetto qui.
Claudiu Creanga,

3

Il software dovrebbe perdonare gli errori dell'utente e completamente intollerante agli errori del programmatore.

Significa che il software dovrebbe essere molto robusto e consentire un ripristino senza problemi per cose come errori di input dell'utente ed errori di configurazione del sistema. Per lo meno un messaggio di errore amichevole che indica dove si è verificato l'errore (casella di input, file di configurazione, argomento della riga di comando, ecc ...) e quale vincolo è stato violato ("deve essere inferiore a X caratteri" ", le opzioni valide sono [X , Y, Z] ", ecc ...) Per maggiore robustezza, il software può suggerire un'alternativa o utilizzare un valore predefinito ragionevole (ma dovrebbe sempre indicare che non utilizza esattamente ciò che l'utente ha specificato).

Non riesco a pensare a molte situazioni in cui è giustificato un nuovo tentativo automatico con impostazioni predefinite diverse, ma ce ne sono alcune (il tentativo automatico di stabilire un collegamento di comunicazione sembra ragionevole). Concordo con @William che questo livello di "ridondanza" è una decisione aziendale.

D'altra parte, non ci dovrebbe essere robustezza di runtime contro l'errore del programmatore. Se ci sono pre-condizioni per i parametri di una funzione, dovrebbero essere verificati con assert, non controlli di runtime. È una mia grande matta da compagnia vedere errori ridondanti controllare e riportare sullo stesso parametro tre o quattro livelli nello stack di chiamate:

 int A(int x)
 {
   if (x==0) return -1
   ...
 }
 int B(int x)
 {
   if (x==0) return -1
   err = A(x)
   if (err) return err;
   ...
 }
 // and so on and so on....

Questa è solo un'ulteriore complessità non necessaria. Non dovresti perdere tempo a capire come una funzione dovrebbe gestire un errore introdotto abusandone un'altra. Se questo è il tipo di "robustezza" a cui ti riferisci, non ne hai bisogno. Sostituiscilo con affermazioni e test di integrazione approfonditi.


3

È una cosa obbligatoria.

C'è un requisito per la robustezza?

"Quando il collegamento di comunicazione fallisce, i pacchetti errati vengono scartati" "Quando il collegamento riprende a funzionare, nessuna transazione viene elaborata due volte"

ci dovrebbero essere casi d'uso per il recupero degli errori (altrimenti come fai a sapere come accadrà?)

Lasciando ai programmatori l'inventiva robustezza mentre procedono (se necessario) si traducono in sistemi "magici".

Tutti i sistemi magici diventano magie schifose nel tempo. La correzione degli errori in background nasconde il verificarsi di guasti, in modo che i guasti non vengano corretti, quindi il sistema alla fine degrada a uno stato di maggiore entropia; ed eseguire come una schifezza, poiché corregge continuamente gli errori. È necessario disporre di un limite per impedire al sistema di entrare in uno stato permanentemente degradato.


2

Alcune operazioni probabilmente giustificano un approccio "riprovare", soprattutto se dipendono da risorse esterne come un database. Ad esempio, se un database non può essere collegato o una query ha esito negativo, è possibile ritentare l'operazione un certo numero di volte prima di rinunciare e lanciare un errore a un livello superiore. Tuttavia, in qualche logica, provare la stessa cosa più volte è spesso un sintomo di cattivo codice e pensiero magico che nasconde problemi reali.


Se il tentativo si ripete senza essere contato e segnalato / visibile, i sistemi si degraderanno e finiranno per funzionare male a causa della loro natura magica di auto-correzione. Utilizzare sempre contatori secchio che perdono (PLOPD4) per segnalare tentativi ed errori. In questo modo, un livello basso viene ignorato, ma i problemi diventano visibili agli utenti.
Tim Williscroft,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.