2010-02-03 12 views
13

È legittimo avere codice di gestione delle eccezioni in un costruttore di classi o dovrebbe essere evitato? Si dovrebbe evitare di avere codice che genera eccezioni in un costruttore?È buona pratica mettere la gestione delle eccezioni in un costruttore?

+2

Lingua? (È importante, in qualche modo, qui ...) –

+0

Intendevo come una domanda indipendente dal linguaggio generale ... Solo standard generali OOP. – froadie

+1

Sì, ma sfortunatamente, questo è un caso in cui la scelta della lingua ha un effetto su tutto tranne le linee guida generali. –

risposta

9

Sì, è perfettamente ragionevole. In quale altro modo si avrebbe una circostanza come questa:

class List { 
    public List(int length) { 
     if(length < 0) { 
      throw new ArgumentOutOfRangeException(
       "length", 
       "length can not be negative" 
      ); 
     } 
     // okay, go! 
    } 
} 

Un List con lunghezza negativa è certamente eccezionale. Non puoi lasciare che questo ritorni al chiamante e fagli pensare che la costruzione abbia avuto successo. Qual è l'alternativa, una funzione membro di istanza CheckIfConstructionSucceeded? Schifo.

O che dire

class FileParser { 
    public FileParser(string path) { 
     if(!File.Exists(path)) { 
      throw new FileNotFoundException(path); 
     } 
     // okay, go! 
    } 
} 

Ancora una volta, questo è un tiro e nient'altro è accettabile.

+1

Non dovrebbe questo codice essere nel metodo setter della proprietà (lunghezza)? – froadie

+3

@froadie: Assolutamente no. – jason

+0

Se la lunghezza non può mai essere negativa, che è quello che sembra se il costruttore non lo consenta, penserei che ci sarebbe un metodo setter setLength() che impone una lunghezza valida. Quale sarebbe un motivo per gestirlo nel costruttore? (Mi manca qualcosa qui?) – froadie

4

Supponendo che sia C++ si sta parlando, sollevando eccezioni è in realtà l'unico modo per segnalare gli errori in un costruttore - quindi questo sicuramente non dovrebbe essere evitato (*)

Per quanto riguarda la gestione delle eccezioni all'interno di costruttori, questo è anche perfettamente valido, a condizione che tu possa effettivamente gestire l'eccezione. Basta seguire la regola comune qui: prendere le eccezioni al livello in cui è possibile gestirle/fare qualcosa di significativo su di loro.

(*) Fino a quando non si è del culto che evita le eccezioni in C++

3

In C++, ctors sono nella posizione migliore per generare eccezioni back up. FAQ:17.2

3

Credo sia valido lanciare un'eccezione in un costruttore per interrompere la creazione dell'oggetto.

2

In generale, ritengo che eccezione codice generatrice dovrebbe essere evitato se possibile costruttori. Tuttavia, questo è molto specifico della lingua: in alcuni linguaggi, i costruttori che lanciano un'eccezione causano problemi irrecuperabili, ma in alcuni altri linguaggi va bene.

Personalmente, cerco di fare in modo che i miei costruttori facciano il meno possibile per mettere l'oggetto in uno stato valido. Ciò, in generale, significherebbe che non verranno lanciati, a meno che non si tratti di un caso veramente eccezionale (che comunque non posso gestire).

+0

Beh, ovviamente dovrebbe essere evitato quando possibile. Questa è una dichiarazione quasi banale. Possibile significa efficacemente se la costruzione dell'oggetto può procedere. Se per qualsiasi motivo la costruzione dell'oggetto non può procedere, deve essere generata un'eccezione. Sono d'accordo con il tuo secondo paragrafo. – jason

+0

@Jason: Tecnicamente, penso che sia un po 'duro. Questa non è una dichiarazione banale, dal momento che spesso si possono prendere decisioni di progettazione per evitare di lanciare un'eccezione in un costruttore. Spetta allo sviluppatore decidere cosa va in un costruttore e cosa viene passato come parametro a metodi che funzioneranno effettivamente, ecc. –

+0

Quindi, in sostanza, si pensa che i costruttori dovrebbero solo fare la minima quantità di lavoro possibile e gestire le eccezioni il codice in un costruttore dovrebbe essere raro? – froadie

3

ovunque ci sia la possibilità di un'eccezione essere gettato, la "best practice" è quello di gestire la cosa, il costruttore o in altro modo.

Lo fa aggiungere un altro strato di complessità al costruttore, poiché è necessario assicurarsi che tutto viene inizializzato correttamente anche se si verifica un errore, ma è meglio che avere il codice buggy :)

0

Certo, non riescono più presto puoi! All'interno dei costruttori alcune convalide dei parametri di input possono andare storte, quindi vale decisamente la pena fallire, invece di procedere con dati costruiti incoerenti.

 

Constructor(Param param){ 
    if(param == null) 
    throw new IllegalArgumentException(...); 
}