Domanda

Supponiamo di avere un metodo

public Patient(int id)
{
    ----
}

che restituisce l'oggetto paziente con un ID. Potrei definire il contratto in 2 modi

  1. Il metodo restituirebbe null se il paziente non esiste
  2. Il metodo genererebbe un'eccezione se il paziente non esiste. In questo caso definirei anche un metodo di query che restituisce true se il paziente esiste nel database o false in caso contrario ...

Quale contratto dovrei usare? Altri suggerimenti?

Aggiornamento: commenta anche questo caso ... Se non è un ID assegnato al database ed è qualcosa che un utente immette nell'interfaccia utente .. come SSN .. allora quale è meglio ..

Commento sul modello Null di Steve che ritengo valido: probabilmente non è una buona idea qui, in quanto sarebbe davvero utile sapere immediatamente quando un ID non esisteva.

E penso anche che il modello Null qui sarebbe piuttosto pesante

Commento di Rob Wells sul lancio dell'eccezione perché ID errato: non penso che un refuso nel nome di un paziente sia una circostanza eccezionale " IMHO

È stato utile?

Soluzione

Tieni presente che andando "oltre il filo" a un altro livello (che sia un database o un server delle applicazioni) è una delle attività più costose che puoi fare - in genere una chiamata di rete impiegherà più ordini di grandezza più a lungo delle chiamate in memoria.

Vale quindi la pena strutturare l'API per evitare chiamate ridondanti.

Considera, se la tua API è così:

// Check to see if a given patient exists
public bool PatientExists(int id);

// Load the specified patient; throws exception if not found
public Patient GetPatient(int id);

Quindi è probabile che tu colpisca due volte il database o che tu faccia affidamento su una buona memorizzazione nella cache per evitarlo.

Un'altra considerazione è questa: in alcuni punti il ??tuo codice potrebbe avere un "bene noto" id, in altri posti no. Ogni posizione richiede una politica diversa sull'opportunità di generare un'eccezione.

Ecco uno schema che ho usato con buoni risultati in passato - hanno due metodi:

// Load the specified patient; throws exception if not found
public Patient GetExistingPatient(int id);

// Search for the specified patient; returns null if not found
public Patient FindPatient(int id);

Chiaramente, GetExistingPatient () può essere creato chiamando FindPatient ().

Ciò consente al codice chiamante di ottenere il comportamento appropriato, generando un'eccezione se qualcosa è andato storto ed evitando la gestione delle eccezioni nei casi in cui non è necessario.

Altri suggerimenti

Un'altra opzione sarebbe il Pattern di oggetti null .

Probabilmente dovresti lanciare un'eccezione. Se hai un id che non punta a un paziente valido, da dove proviene? Probabilmente è successo qualcosa di molto brutto. È una circostanza eccezionale.

MODIFICA: Se stai facendo qualcosa di diverso da un recupero basato su numeri interi, come una ricerca basata su testo, la restituzione di null va bene. Soprattutto perché in quel caso stai restituendo una serie di risultati, che potrebbero essere più di uno (più di un paziente con lo stesso nome, la stessa data di nascita o qualunque sia il tuo criterio).

Una funzione di ricerca dovrebbe avere un contratto diverso da una funzione di recupero.

Dipende:

Se si considera che l'operazione normale porterà a un numero di pazione che non corrisponde a un file nel DB, è necessario restituire un record vuoto (NULL).

Ma se ti aspetti che un determinato ID debba sempre raggiungere un record, quando uno non viene trovato (il che dovrebbe essere raro) usa un'eccezione.

Altre cose come un errore di connessione DB dovrebbero generare un'eccezione.
Come previsto in situazioni normali, la query al DB funzionerà sempre (sebbene possa restituire 0 record o meno).

P.S. Non vorrei restituire un puntatore. (Chi possiede il puntatore ??)
Vorrei restituire un oggetto che potrebbe o meno avere il record. Ma che puoi interagire per l'esistenza del record all'interno. Potenzialmente un puntatore intelligente o qualcosa di leggermente più intelligente di un puntatore intelligente che comprende il cotext.

Per questa circostanza, vorrei che il metodo restituisse null per un paziente inesistente.

Tendo a preferire l'uso di eccezioni per favorire un grave degrado in caso di problemi con il sistema stesso.

In questo caso, è probabilmente mosdt:

  1. un refuso nell'ID del paziente se è stato inserito in un modulo di ricerca,
  2. un errore di immissione dei dati o
  3. un problema relativo al flusso di lavoro in quanto il record del paziente non è stato ancora inserito.

Quindi, restituendo un valore null anziché un'eccezione.

Se si fosse verificato un problema durante il contatto con il database, il metodo avrebbe sollevato un'eccezione.

Modifica: Ho appena visto che l'ID paziente nella firma era un numero intero, grazie Steven Lowe, quindi ho corretto il mio elenco di motivi.

Il mio punto di base sul delineare quando utilizzare le eccezioni (per errori di sistema) rispetto ad altri metodi di restituzione di un errore (per semplici errori di inserimento dati) rimane comunque valido. IMHO.

HTH

applausi,

Rob

In una situazione semplice come questa 1. sembra essere più che sufficiente. Potresti voler implementare qualcosa come un metodo di callback che il client chiama per sapere perché ha restituito null. Solo un suggerimento.

prendendo la tua descrizioneg al valore nominale, probabilmente avrai bisogno di entrambi:

  • ID errati sono errori / eccezioni, come ha sottolineato Adam, ma
  • se ti vengono dati ID altrove che potrebbero essere scomparsi, avrai bisogno del metodo di query per verificarli

Supponendo di averlo letto correttamente ... Quando si chiama Patient (100), verrà restituito un riferimento a un oggetto per un paziente con un ID di 100. Se non esiste un paziente con un ID di 100, penso che dovrebbe restituire null. Le eccezioni sono IMO abusate e questo caso non lo richiede. La funzione ha semplicemente restituito un valore nullo. Non ha creato alcun caso errato che potrebbe causare l'arresto anomalo dell'applicazione (a meno che, naturalmente, non si sia trattato di tale null e lo sia passato ad un'altra parte dell'applicazione).

Avrei sicuramente quella funzione restituire 'null', specialmente se faceva parte di una ricerca, in cui un utente avrebbe cercato un paziente con un determinato ID e se il riferimento all'oggetto fosse finito null, avrebbe semplicemente affermato che non esiste nessun paziente con quell'ID.

Genera un'eccezione.

Se si restituisce null, digitare questo codice:

Console.WriteLine(Patient(id).Name);

fallirebbe con una NullReferenceException se l'id non esiste, il che non è utile come dire una PatientNotFoundException (id). In questo esempio, è ancora relativamente facile rintracciare, ma considera:

somePatient = Patient(id)

// much later, in a different function:

Console.WriteLine(somePatient);

Informazioni sull'aggiunta di una funzione che controlla l'esistenza di un paziente: si noti che ciò non impedirà completamente PatientNotFoundExceptions. Ad esempio:

if (PatientExists(id))
    Console.WriteLine(Patient(id).Name);

: un altro thread o un altro processo potrebbero eliminare il paziente tra le chiamate a PatientExists e Patient. Inoltre, ciò significherebbe due query di database anziché una. Di solito, è meglio provare la chiamata e gestire l'eccezione.

Nota che la situazione è diversa per le query che restituiscono più valori, ad es. come un elenco; qui, è opportuno restituire un elenco vuoto se non ci sono corrispondenze.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top