Implementazione dello stack in base alla progettazione e alla programmazione difensiva

1

Sto provando a scrivere il codice Stack usando le due tecniche, ad esempio Design by Contract vs Defensive Programming, ma non sono sicuro se sto facendo bene o no. Non sto lanciando nessun tipo di eccezione o errore nella progettazione per contratto assumendo tutto gli input saranno corretti.

    
posta Grad student 08.10.2016 - 01:49
fonte

2 risposte

2

Design per contratto

Nel tuo esempio 1, nessun controllo è fatto. L'implementazione presuppone che il cliente rispetti i termini del contratto. Quindi sì, potresti essere tentato di affermare che si tratta di DBC.

Tuttavia ciò che manca è l'espressione del tuo contratto: non ci sono indizi di pre-condizioni, post-condizioni e invarianti nel codice. Questo è mancante.

In C ++ inseriresti assert() all'inizio e alla fine di ogni funzione. Questi dovevano fare un duro controllo (e interrompere in caso di infrazione) durante il debug, ma sarebbero saltati in versione di produzione.

In Java, annoteresti il tuo codice con javadoc tag @pre , @post e @inv in i commenti per la documentazione, ma anche per l'elaborazione come spiegato qui con strumenti come jContracts o strumenti / librerie simili .

Programmazione difensiva

Nel secondo esempio, si attiva attivamente il controllo se sono soddisfatte le aspettative del contratto e si prende un percorso alternativo di esecuzione per gestire il caso imprevisto (qui con eccezioni). Questo sembra corrispondere all'anticipazione attesa dalla programmazione difensiva.

    
risposta data 08.10.2016 - 02:58
fonte
4
  1. Aiuta a sapere in quale lingua stai lavorando, specialmente se quella lingua ti sta fornendo alcune funzioni di sicurezza, come il controllo dei limiti di array. Ad esempio, se stai lavorando in Java o C #, otterrai il controllo degli array che generano automaticamente quando qualcosa non va, ma se lavori in C / C ++, il tuo programma potrebbe funzionare per un po 'come un ferito animale quindi scappa e muori da qualche altra parte.

  2. La nozione di Design by Contract va oltre l'interfaccia (mere firme di metodo) a precondizioni e post-condizioni che devono essere specificate , cosa che non hai fatto. Ad esempio, non hai specificato quale sia il comportamento se lo stack è pieno (dovrebbe far crescere lo spazio di archiviazione o generare un'eccezione o altro), o scoppiare quando è vuoto. Inoltre, in Design by Contract, ci aspettiamo che le precondizioni e le post-condizioni siano monitorate, quindi il test per loro è valido. (Un linguaggio Design by Contract lo supporterebbe con i costrutti linguistici, ma lo si può fare in altri linguaggi tramite assert o tiri condizionali.) Ad esempio, se il popping di uno stack vuoto produce un valore nullo rispetto a un'eccezione. Design by Contract non usa la lettura di un'implementazione per determinare quel contratto, quindi dovresti specificare esplicitamente quel tipo di informazioni da qualche parte (ad esempio nel JavaDoc, forse). Non sono stati documentati costruttori, quindi non siamo in grado di capire quale potrebbe essere la fine del contratto anche dal punto di vista della firma di un metodo.

  3. Tutto ciò che hai fatto con Defensive è controllare gli errori che alcune lingue potrebbero fare comunque per te (o meno a seconda della lingua scelta). Quindi, questo è buono o non completamente necessario a seconda della lingua, ma dipende anche dal metodo di registrazione che si desidera fare ( println non è la forma migliore di registrazione, però). Tuttavia, potresti voler lanciare qualche eccezione più specifica piuttosto che consentire al runtime di sceglierne uno, ma in questo caso semplice, probabilmente lascerei che il runtime esegua il controllo e il lancio dei limiti per me.

  4. Se stai programmando in modo difensivo, programmerai di proteggerti dai tuoi bug, non solo quelli dei tuoi chiamanti. Ciò significa che l'operazione push dovrebbe controllare >= size , non == size , perché chissà se il tuo codice consentisse altrimenti che la dimensione fosse impostata arbitrariamente.

  5. Se stai usando una lingua con array a base zero, dovresti postare incremento (in push) e pre-decremento (in pop), altrimenti perderai il primo elemento nell'array. (E se lo aggiusti, allora il controllo delle dimensioni dovrebbe essere compensato da 1.) Lo spreco imprevisto, con conseguente incapacità di offrire la capacità pubblicizzata, potrebbe anche essere una violazione del contratto quando il chiamante scoppia troppe volte.

risposta data 08.10.2016 - 02:22
fonte

Leggi altre domande sui tag