Tach!
klingt sehr einleuchtend! Hast du mir ein kuzes Anwendungsbeispiel geben?
Was muss denn wer wissen? Der Controller, oder welcher Teil auch immer die Validierung anstößt, muss wissen ob das Model valide ist. Das ist ein Funktionsaufruf mit booleschem Ergebnis. Und die View will am Ende wissen, welche Meldungen generell und welche zu bestimmten Feldern ausgegeben werden sollen. Also muss der Validierungsprozess auch noch eine solche Struktur liefern. Eigentlich ist dies das Hauptergebnis und die boolesche Information nur für Entscheidungen wichtig. Ihren Wert kann man auch aus der Anzahl der Fehlermeldungen ermitteln (0 == valide). Das wäre also das eine Interface.
Der Validator hingegen muss auf das Model zugreifen können, um die Werte zu prüfen. Er braucht auch ein Regelwerk, das er abarbeiten muss. Das wird wohl am besten ein Array mit den Regeln sein.
Die Regeln selbst arbeiten unterschiedlich. Eine Required-Regel braucht nur einen Wert, den sie auf null oder Leerstring testen muss. Eine Stringlängen-Regel braucht den Wert sowie eine Min- und Max-Angabe. Eine Passwort-Gleichheit-Regel braucht stattdessen zwei Werte. Die einzige Gemeinsamkeit ist die Aussage, ob die Regel eingehalten wurde oder nicht. Das könnte man so lösen, dass die benötigten Angaben als Parameter in den Konstruktor gegeben werden. Je nach Regel sieht der unterschiedlich aus. Das Interface, das die Regel-Klassen implementieren, besteht nur aus einem Funktionsaufruf, der die eigentliche Prüfung an den Werten ausführt, die der Konstruktor entgegengenommen hat, und true/false liefert. Eine andere Möglichkeit wäre, dass die Prüfung den Meldungstext produziert, oder null/false, wenn es nichts zu meckern gibt, oder wie auch immer man das implementieren möchte.
zumal muss ich ja auch noch die Superklassen irgendwie einbetten.
Da stellt sich die Frage, ob man dafür überhaupt Superklassen braucht. Gibt es denn Code, den man mehrfach implementieren würde und den auszulagern sinnvoll ist?
Bei den Regeln eher nicht. Beim Validator wird das jedoch der Fall sein. Wenn deine Models typischerweise POPOs sind (Plain Old PHP Object), dann sind die Validatoren zwar je nach Model mit unterschiedlichen Regelwerken auszustatten, aber die Abarbeitung wird immer nach demselben Prinzip ablaufen. Letzteres wäre eine Aufgabe für die Superklasse.
Andererseits kann es sich ergeben, dass das Model kein POPO ist, sondern irgendeine andere Datenstruktur, dass braucht man eine andere Ausführung als die für den POPO-Validator. Also wird dieser Validator nicht von der Superklasse erben, das Interface in Richtung Controller bleibt aber dasselbe.
PHP ist je eine Sprache, die normalerweise im Quelltext ausgeführt wird. Unter anderem deshalb ist es üblich, dass die Frameworks alle Open Source sind. Man kann da also durchaus auch mal durch diese schauen, wie deren Vorgehensweise ist. Am besten fängt man da in der Dokumentation an, um zu sehen, wie deren Implementation anzuwenden ist. Und wenn das gefällt, kann man ja den Code dazu anschauen.
Das was ich beschrieben habe, ist nur eine Möglichkeit, nicht aber die einzige oder gar die einzig wahre. Mir persönlich gefallen beispielsweise solche Vorgehensweisen nicht, bei denen man jede Menge Strings angeben muss, um zu beschreiben, was man erreichen möchte. Dabei muss man immer wissen oder in der Doku nachschauen, wie der String konkret zu schreiben ist, und IDEs mit Autovervollständigung können dabei so gut wie nicht unterstützend mithelfen. Wenn schon Strings, dann sollten die hinter Klassenkonstanten versteckt sein. Dann kann man den Namen der Klasse eingeben und bekommt alle Möglichkeiten aufgezählt.
Um mal zwei Beispiele zu nennen von Frameworks die mir spontan eingefallen sind, deren Vorgehensweise mir nicht gefällt: Zend Framework - Forms and actions: die Anwendung der InputFilter als verschachteltes Array in bis zu vier Ebenen. Laravel Validation: mit |
verkettete Stringwürste.
dedlfix.