Sven Rautenberg: Methoden-Parameter: immer alles validieren?

Beitrag lesen

Moin!

Wie ist das bei PHP5 genau? Muss ich da wirklich IMMER alles prüfen? Ist also sowas unbedingt nötig:

public function x(int $value)
{
  if (!is_int($value)) { throw new Exception();}
}
x('a');

  
Kurze Frage, lange Antwort.  
  
Nein, du mußt nicht alles immer prüfen. Jedenfalls nicht diese sinnlosen Details wie "ist die Variable wirklich ein Integer", sofern dieses Detail keine Rolle spielt.  
  
Was du aber tun solltest, ist dich mit testgetriebener Entwicklung zu beschäftigen. Denn das würde dir diverse Dinge erleichtern und teilweise erst erlauben, darunter:  
 - hohe Softwarequalität, geringe nachträglich zu behebende Fehlerzahl  
 - Freiheit, alle Funktionen/Methoden beliebig neuzuschreiben, ohne das bestehende Gesamtsystem kaputtzumachen  
 - die Sicherheit, dass eine Funktion/Methode im Live-Einsatz genau das macht, was du im Test spezifiziert hast.  
  
Gerade der letzte Punkt ist für deine Fragestellung hier entscheidend. Wenn du testgetriebene Entwicklung anfängst, dann schreibst du zuallererst mal einen Test, der deine Funktion/Methode, die du zu schreiben gedenkst, auf die allereinfachste Art aufruft. Was natürlich scheitert, weil deine Funktion noch gar nicht existiert. Dadurch vergißt du nicht, alle notwendigen Dateien auch wirklich einzubinden und die Namen korrekt zu benennen. Am Ende dieser ersten Runde hast du einen Test, der grob nur die Existenz der Funktion testet, und eine korrekte, aber leere Funktion.  
  
Dann kommt der nächste Test: Du gibst einen gültigen Parameter hinein und erwartest ein korrektes Ergebnis - was mangels Funktionscode noch scheitert. Und schreibst dann die Funktion so, dass auch dieser Test erfüllt wird.  
  
Jetzt wirst du frivol und schickst im Test einen ungültigen Parameter in die Funktion und erwartest ebenfalls ein für diesen Fall korrektes Ergebnis. Aber was wäre denn ein korrektes Ergebnis für einen ungültigen Parameter? Und was ist überhaupt ein ungültiger Parameter?  
  
Es ist ja nicht so, dass es in PHP einen Unterschied macht, ob man x=10 oder x='10' hat. Beide Variablen werden in Rechnungen als Zahl und in Stringoperationen als String behandelt werden. Man muß also nicht wirklich prüfen, ob man es wirklich mit einem Integer zu tun hat, wenn diese Frage keine Rolle spielt, oder vernachlässigbar ist, weil sie zu keinem Fehler führt.  
  
Es wäre also in den Tests kein Problem, wenn vier Szenarien geprüft werden:  
1\. Integer 10  
2\. Integer 0  
3\. String '10'  
4\. String 'xyz'  
  
Für alle diese geprüften Fälle muß es definierte Resultate geben. Vielleicht ist Integer 0 der im Zahlenbereich unerlaubte Fall. Dann würde schon automatisch auch 'xyz' behandelt werden, weil dessen Zahlwert auch 0 ist. Oder es kommt darauf an, Integer von Strings zu unterscheiden - was genau Sache ist, hängt ja extrem von der zu lösenden Aufgabe ab.  
  
Im übrigen ergeben sich weitere zu schreibende Tests für Testfälle in der Regel durch entdecktes Fehlverhalten des Gesamtsystems. Wenn im Gesamtsystem der Parameter dieser Funktion sowieso garantiert ein Integer ist (weil Tests einer anderen Funktion das sicherstellen), braucht man das Vorhandensein von Strings in dieser Funktion ja nicht prüfen.  
  
Und noch ein Wort zu Exceptions: Ich mag sie nicht. Sie trennen Fehlerbehandlung von Normalbehandlung, und das ist durchaus nicht so wundervoll, wie einem oft eingeredet wird. Erst dadurch entstehen nämlich so supertolle Meldungen wie "Ein unbekannter Fehler ist aufgetreten!", der weder dem Benutzer noch dem Programmierer noch irgendwas hilfreiches sagt. Fehlerzustände sollte man nicht "werfen", sondern abfangen und das Beste draus machen. Eine mögliche Definition von "das Beste" wäre beispielsweise ein Flag "ups, die Abfrage ist schiefgegangen, das gelieferte Resultat ist nur hilfsweise zu verstehen", zusammen mit einem gültigen, aber im Sinne des Kontextes "leeren" regulären Ergebnis. Beispielsweise geht die Datenbankabfrage schief. Das Ergebnis ist dann $ok=false, $data=array(). Mit dem Datensatz kann das abfragende Programm mit Sicherheit weiterarbeiten, leere DB-Ergebnisse können ja immer mal vorkommen. Es kann aber auch explizit den Abfrageerfolg ermitteln und dadurch verzweigen und den Fehlerfall vom Benutzer lösen lassen.  
  
 - Sven Rautenberg

-- 
"Love your nation - respect the others."