Quando utilizzare il modello del valore di ritorno xxxResult?

3

Ho un metodo che ha bisogno di restituire più valori indipendentemente dal fatto che abbia avuto successo o meno, quale sia la chiave utilizzata per chiamare l'api e se ha avuto successo il risultato di ritorno. Ecco un metodo più concreto,

public xxxResult PublishMessage(){

   // dynamically calculate the key
   try {
         // call the third party api and get the result
         // return key-used, result and successful flag
   }
   catch(Exception ex){
      // return key-used, null result and not-successful flag
   }
}

È logico creare una classe xxxResult qui o c'è qualche altro modo di progettazione che mi manca qui? Quando dovremmo usare il modello xxxResult.

    
posta user960567 10.11.2018 - 21:29
fonte

3 risposte

5

Odio le classi xxxResult / xxxReponse. È solo un cattivo nome

Normalmente sembrano apparire quando si serializza una risposta a un oggetto json per passare da un'API REST e si desidera includere alcuni metadati, come un errore che si verifica oltre al risultato effettivo.

Ma ci sono modi migliori per gestire questo senario, ovvero restituire un codice di errore HTTP e un messaggio di errore invece di un risultato.

Nel tuo caso specifico separerei i problemi di generazione della chiave e di pubblicazione dei messaggi per evitare il tipo di ritorno composto e per evitare il problema di un crash effettivo piuttosto che un'eccezione che significa perdere una chiave

Altri casi che ho visto sono quelli in cui si ha un tipo "Risultato di una Proccess" di tipo legittimo che in realtà non ha alcun significato. Qui devi solo essere più creativo con la tua denominazione se vuoi evitare molte classi xxxResult.

ReportGenerationResult è un report, ToolCalibrationResult è un ErrorMeasurement, ecc.

    
risposta data 10.11.2018 - 22:26
fonte
5

Se la tua lingua supporta le tuple , questa potrebbe essere una soluzione. Le tuple hanno diversi vantaggi in questo caso:

  • Il metodo è più facile da scrivere.

    try {
        return (true, obj);
    } catch (...) {
        return (false, null);
    }
    
  • Anche il codice del chiamante è più semplice.

    var success, response = PublishMessage();
    
  • Non è necessario creare una classe aggiuntiva.

Se la lingua non supporta le tuple, l'altra opzione prevede che il metodo restituisca un tipo in caso di successo, un altro tipo in caso di errore . Il chiamante dovrà controllare il tipo del valore restituito e agire di conseguenza per un tipo o per un altro.

try {
    return new Key(...);
} catch (...) {
    return new ApiError(...);
}

Un'altra soluzione è avere un valore magico : dire null per indicare un errore. Sebbene più semplice dell'approccio precedente, non lo consiglierei . Avere due tipi rende possibile estendere la risposta in seguito. Ad esempio, la risposta restituita per errore può contenere il codice di errore o il messaggio di errore.

    
risposta data 10.11.2018 - 22:18
fonte
2

Considera un po 'di polimorfismo. Questo

public xxxResult PublishMessage(){

   // dynamically calculate the key
   try {
         // call the third party api and get the result
         // return key-used, result and successful flag
   }
   catch(Exception ex){
      // return key-used, null result and not-successful flag
   }
}

può diventare

public Message PublishMessage(){
   Message message; 

   // dynamically calculate the key
   Key key = calculateKey();

   try {
         // call the third party api and get the result
         APIResult apiResult = thirdPartyAPI.getResult();

         // return key-used, result and successful flag
         message = new MessageSuccess(key, apiResult);
   }
   catch(Exception ex){
      // return key-used, null result and not-successful flag
      message = new MessageFailure(key);
   }
   finally{
       return message;
   } 
}

Il chiamante NON deve controllare il tipo del valore restituito. Qualunque sia il codice che usa questo non deve sapere o preoccuparsi di quello che è successo. L'eccezione è stata gestita e il messaggio stesso saprà cosa fare e ha tutto il necessario per farlo. In un modo o nell'altro.

Ma per favore usa nomi migliori di questi.

    
risposta data 11.11.2018 - 06:44
fonte

Leggi altre domande sui tag