[Java] Die Geschichte einer wirklich beängstigenden switch-Anweisung
Einführung
Vor langer Zeit habe ich die Geschichte zusammengefasst, als ich die switch-Anweisung durcheinander gebracht habe.
Es ist eine sehr peinliche Geschichte, aber ich habe einen Artikel zusammengestellt, um zu verhindern, dass ähnliche Unfälle erneut passieren.
1. Ausgangszustand
- Wie TestServlet.java unten wurde die switch-Anweisung zum Zuweisen der Verarbeitung basierend auf dem Wert des Anforderungsparameters verwendet.
- Tatsächlich lag die Anzahl der bedingten Verzweigungen nahe bei 10, daher habe ich die switch-Anweisung anstelle der if-Anweisung übernommen.
TestServlet.java
@WebServlet("/TestServlet")
public class TestServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//Parameter anfordern"id"Holen Sie sich den Wert von.
int id = Integer.parseInt(request.getParameter("id"));
// "id"Prozesse werden basierend auf dem Wert von verteilt.
switch(id) {
case 1:
//Prozess 1-A
break;
case 2:
//Prozess 2-A
break;
case 3:
//Prozess 3-A
break;
default:
//Standardverarbeitung
break;
}
...
}
}
2. Renovierung durch zusätzliche Funktionen
- Da die Verarbeitung in der switch-Anweisung mit dem Hinzufügen von Funktionen zugenommen hat, ist die switch-Anweisung insgesamt aufgebläht, wie unten gezeigt.
- Zu diesem Zeitpunkt, während ich den Code wiederholt schreibe und lösche, ** scheint es, dass ich versehentlich eine Unterbrechung gelöscht habe **.
- Ich habe nicht bemerkt, dass ich die Pause gelöscht habe, weil die switch-Anweisung aufgebläht war ...
- ** Das Löschen von break verursacht übrigens keinen Kompilierungsfehler! ** ** **
TestServlet.java
@WebServlet("/TestServlet")
public class TestServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//Parameter anfordern"id"Holen Sie sich den Wert von.
int id = Integer.parseInt(request.getParameter("id"));
// "id"Prozesse werden basierend auf dem Wert von verteilt.
switch(id) {
case 1:
//Prozess 1-A
//Prozess 1-B
//Prozess 1-C
break;
case 2:
//Prozess 2-A
//Prozess 2-B
//Prozess 3-C (★ Ich habe die Pause sofort danach gelöscht...)
case 3:
//Prozess 3-A
//Prozess 3-B
//Prozess 3-C
break;
default:
//Standardverarbeitung
break;
}
...
}
}
3. Unfall aufgetreten
- Einige Zeit nach der Freigabe des Codes mit zusätzlichen Funktionen fragte ein Benutzer, ob "das System sich seltsam verhält".
- Ich hätte alle Tests vom Komponententest bis zum Systemtest bestehen sollen, aber als ich mich eingehend damit befasste, stellte ich fest, dass das Verarbeitungsergebnis seltsam war.
Wert der Parameter-ID |
Erwartetes Verarbeitungsergebnis |
Tatsächliches Verarbeitungsergebnis |
1 |
X |
X |
2 |
Y |
Nicht Y. |
3 |
Z |
Z |
Andere |
α |
α |
4. Grund für den Unfall
- An dem Punkt, an dem break aus der switch-Anweisung verschwand, trat ein völlig unbeabsichtigter ** "Durchfall" ** auf.
- Wie oben erwähnt, verursacht ein Unterbrechungsfehler keinen Kompilierungsfehler. Wenn Sie den Code also nicht sorgfältig lesen, werden Sie ihn vermissen ...
- Der Grund, warum der Test bestanden wurde, ist, dass "der Test die bedingte Verzweigung nicht abdeckte".
- Das Erstellen eines Tests, der alle bedingten Zweige abdeckt, kann jedoch eine entmutigende Aufgabe sein ...
5. Was ist nach dem Unfall zu tun?
- Ich denke nicht, dass es die beste Antwort ist, aber ich sagte "benutze die switch-Anweisung nicht unnötig".
- Da die Ursache für diesen Unfall "eine aufgeblähte switch-Anweisung mit schlechter Sichtbarkeit" ist, habe ich die Regel aufgestellt, dass "bei Verwendung einer switch-Anweisung davon ausgegangen wird, dass die gesamte switch-Anweisung schlank und die Sichtbarkeit gut ist".
- Erstens ist "Code mit schlechter Sichtbarkeit" selbst ein Problem, aber um "unbeabsichtigtes Durchfallen" zu verhindern, hielt ich es für sicherer, die switch-Anweisung nicht unachtsam zu verwenden. (Vielleicht "Switch Statement Allergie" ...)
- Ich habe mehr denn je versucht, einen Unit-Test durchzuführen.
- Selbst mit geringfügigen Änderungen haben wir Wege gefunden, um fehlende Testmuster zu beseitigen, z. B. die Verwendung der Entscheidungstabelle zur Identifizierung von Testmustern. (Es scheint, dass Sie zu wenig Bewusstsein haben ...)
- Zu dieser Zeit haben wir begonnen, objektive Indikatoren zu verwenden, z. B. die Überprüfung der Abdeckungsrate auf Filialebene mit Cobertura.
Referenz-URL