2013-05-16 12 views
6

Ich habe eine SchnittstelleSchnittstelle Implementierung startet verschiedene Ausnahmen

public interface DataDAO { 
    public void doSomething() throws Exception; 
} 

Lassen Sie uns sagen, dass es zwei Implementierungen, eine, die Datenbank verwendet die Daten und ein anderes zu erhalten, die einen Webservice verwendet.

Wie Sie bereits sehen können, ist das Problem die super generische Ausnahme gestartet. Da beide Implementierungen die gleiche Art von Ausnahme auslösen müssen.

Die Jdbc-Implementierung löst nur SQLException aus, während die Webservice-Implementierung nur die IOException erhöht.

Frage ist, wie kann ich die Schnittstelle eleganter machen, so dass ich eine richtige Ausnahme erfassen?

Das erste, was ich aber meine eigene Ausnahme war die Schaffung und es an der Schnittstelle Ebene erklären accordinly

public interface DataDAO { 
    public void doSomething() throws MyCoolException; 
} 

Und dann natürlich implementieren.

Frage ist, macht das Sinn? Ich habe nie eigene Ausnahmen erstellt, daher bin ich mir nicht sicher, ob das Sinn macht oder nicht. Was sollte ich beim Erstellen von MyCoolException beachten?

+0

Wie wäre es mit Inspiration von Spring und dem Einschluss in RuntimeExceptions? –

+0

@AjayGeorge Nun, ich möchte, dass diese Ausnahmen von der oberen Ebene behandelt werden, so dass sie RuntimExceptions für mich nicht gültig ist, korrigieren Sie mich, wenn ich falsch liege :) –

+0

Nun könnten Sie RuntimeExceptions ableiten und dann eine [DataAccessException] (http : //static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/dao/DataAccessException.html) wie im Frühling. –

Antwort

4

Das erste Ding, das ich war, errichtete meine eigene Ausnahme und erklärt es auf der Schnittstellenebene (...) macht das Sinn?

Ja, es macht Sinn und ich denke, es ist der beste Weg, um mit diesen Situationen umzugehen.

ich ein Kick-off Beispiel dafür sorgen werden (basierend auf dem aktuellen Code):

public class MyCoolException extends Exception { 
    public MyCoolException() { 
    } 
    public MyCoolException(String message) { 
     this.message = message; 
    } 
} 

public interface DataDAO { 
    public void doSomething() throws MyCoolException; 
} 

public class DataDAOJdbc implements DataDAO { 
    public void doSomething() throws MyCoolException { 
     //Implement 
     try { 
     } catch (SQLException e) { 
      //handle the exception 
      logger.error("Error!", e); 
      //throw your custom exception 
      throw new MyCoolException(e.getMessage()); 
     } 
    } 
} 

public class DataDAOWebService implements DataDAO { 
    public void doSomething() throws MyCoolException { 
     //Implement 
     try { 
     } catch (IOException e) { 
      //handle the exception 
      logger.error("Error!", e); 
      //throw your custom exception 
      throw new MyCoolException(e.getMessage()); 
     } 
    } 
} 
+1

Hmm, das ist ein Nitpick, aber ich würde empfehlen, die cause-Ausnahme (anstatt ihrer Nachrichten-Zeichenfolge) mit 'MyCoolException' zu umhüllen und darauf zu warten, die ganze Geschichte zu protokollieren, wenn' MyCoolException' behandelt wird. –

+1

Ich stimme absolut mit Paul überein, und ich würde sogar so weit gehen zu sagen, dass das wichtigste ist, wenn man eine eigene Ausnahme schreibt (* vor allem * wenn es um eine weitere Ausnahme geht): Ohne den ursprünglichen Grund verliert man * viel * Informationen, die beim Debuggen von Problemen absolut notwendig sein könnten. –

+0

@PaulBellora Ich stimme Ihnen zu, Leute, deshalb habe ich gesagt, dass dies ein einfaches Beispiel ist und protokolliere die Ausnahme, bevor die benutzerdefinierte Ausnahme erneut ausgelöst wird. –

2

können Sie einen generischen Typ verwenden, um die Schnittstelle geworfen zu definieren:

public interface DataDAO<E extends Throwable> { 
    public void doSomething() throws E; 
} 

Dann wird Ihr Implementationen würde wie folgt aussehen:

public class DataDAOJdbc implements DataDAO<JDBCException> { 
    public void doSomething() throws JDBCException { 
     //Implement 
    } 
} 

public class DataDAOWebService implements DataDAO<WebServiceException> { 
    public void doSomething() throws WebServiceException { 
     //Implement 
    } 
} 

Dies ist jedoch den Nachteil hat, dass man sich nicht mehr Handle alle Ausnahmen auf die gleiche Weise, es sei denn, Sie fangen nur Exception (was ziemlich viel negiert den gesamten Punkt).

+2

Aber angenommen, das OP wollte Code für die Schnittstelle, nicht für die Implementierung codieren, würde dies nicht helfen, Sites überhaupt aufzurufen. –

+0

@PaulBellora guten Punkt, haben Sie eine bessere Idee? –

+0

Dieser Ansatz bricht Polymorphismus. Eine benutzerdefinierte Ausnahme sollte verwendet werden. – Mikhail

1

tut dies Sinn?

Ja, tut es. Durch die Deklaration, dass doSomething eine bestimmte geprüfte Ausnahme auslöst, signalisieren Sie Anrufern der Methode, dass sie nur diese spezifische Ausnahme abfangen und behandeln müssen. Durch das Erklären von einfach throws Exception würden Anrufer ermutigt werden, alle Exception s zu erfassen und damit umzugehen, die sogar Laufzeitausnahmen wie NullPointerException enthalten.

Was muss ich bei der Erstellung von MyCoolException beachten?

Es könnte so einfach wie die folgenden sein:

public final class MyCoolException extends Exception { 

    public MyCoolException(Throwable cause) { 
     super(cause); 
    } 
} 

So Ihre benutzerdefinierte Ausnahme einfach als Wrapper für die Ursache Ausnahme handeln würde, was auch immer es sein mag. Wenn möglich, könnten Sie eine Nachricht mit zusätzlichen Informationen hinzufügen, die beim Debuggen hilfreich sein könnten. Wenn MyCoolException abgefangen wird, können Sie es durch Aufrufen von getCause() auspacken oder es an einen Aufruf an ein Protokollierungsframework weiterleiten (sein Stacktrace enthält die Ursache Ausnahme).

Verwandte Themen