Ich arbeite an einem System, mit dem Administratoren Formulare definieren können, die Felder enthalten. Die definierten Formulare werden dann zur Eingabe von Daten in das System verwendet. Manchmal werden die Formulare von einem Menschen über eine GUI ausgefüllt, manchmal wird das Formular basierend auf Werten ausgefüllt, die von einem anderen System gemeldet wurden.
Für jedes Feld kann der Administrator eine Validierungsregel definieren, die die zulässigen Werte für das Feld begrenzt. Die Validierungsregeln können von "Der in das Feld eingegebene Wert muss wahr oder falsch sein" bis zu "Der in das Feld eingegebene Wert muss in Spalte A von Tabelle B in der Datenbank vorhanden sein" reichen. Der Administrator kann die Validierungsregel für das Feld jederzeit ändern.
Welcher Ort ist Ihrer Meinung nach in diesem Szenario am besten geeignet, um zu überprüfen, ob jedes Feld korrekt ausgefüllt ist? Ich habe derzeit zwei Hauptansätze im Sinn:
Option 1: Validieren im Domänenmodell
Jedes Feldobjekt würde die vom Administrator angegebene Validierungsregel enthalten. Die Field-Objekte hätten auch einen Verweis auf einen IValidator. Wenn versucht wird, den Wert des Felds festzulegen, übergibt das Feld den angegebenen Wert und die Validierungsregel an den IValidator. Wenn der angegebene Wert nicht gültig ist, wird eine ValidationException ausgelöst und in der GUI / Schnittstelle zum anderen System entsprechend behandelt.
Vorteile:
- Starker Schutz gegen Felder, denen versehentlich Werte zugewiesen wurden, die gegen die Validierungsregel verstoßen
Nachteile:
Die Datenzugriffsschicht muss in der Lage sein, die Validierung zu umgehen und Felder zu erstellen, die gegen die aktuelle Validierungsregel verstoßen. Obwohl der Administrator die Validierungsregel für ein Feld geändert hat, müssen wir weiterhin in der Lage sein, Feldobjekte basierend auf den alten Daten zu erstellen, z. B. beim Rendern eines Formulars, das vor Jahren ausgefüllt wurde. Dies könnte möglicherweise behoben werden, indem die aktuelle Validierungsregel bei jedem Speichern des Felds gespeichert wird.
In diesem Entwurf hat das Feldmodell über den IValidator eine indirekte Verbindung zur Datenzugriffsschicht / zum Datenzugriffsrepository. Die Injektion von Diensten / Repositorys in Domänenmodelle scheint allgemein verpönt zu sein .
Option 2: In einem Dienst validieren
Stellen Sie sicher, dass alle Versuche, den Wert eines Felds festzulegen, einen Dienst durchlaufen, der sicherstellt, dass die Validierungsregel gilt. Wenn die Validierungsregel verletzt wird, lösen Sie eine ValidationException aus.
Natürlich würde die Datenzugriffsschicht den Dienst nicht verwenden, wenn Feldobjekte erstellt werden, die zuvor in der Datenbank beibehalten wurden .
Vorteile:
Verstößt nicht gegen das Denken "Keine Services / Repositorys in Ihre Domain-Modelle einfügen".
Die aktuelle Validierungsregel muss nicht beibehalten werden, wenn das Feld beibehalten wird. Der Service kann einfach die aktuelle Validierungsregel für das Feld nachschlagen. Beim Betrachten von Verlaufsdaten wird der Wert des Felds nicht geändert.
Nachteile:
- Keine Garantie, dass alle Logik, die den Service zum Festlegen des Feldwerts verwenden sollte, dies tatsächlich tut. Ich sehe dies als großen Nachteil; Alles, was es zu brauchen scheint, ist jemand, der "thisField.setValue (thatField.getValue ())" schreibt, und die Validierungsregel von thisField könnte verletzt werden, ohne dass jemand klüger ist. Dies könnte möglicherweise gemindert werden, indem sichergestellt wird, dass der Wert des Felds mit der Validierungsregel übereinstimmt, wenn die Datenzugriffsschicht das Feld beibehalten soll.
Ich bevorzuge derzeit Option 1 gegenüber Option 2, hauptsächlich weil ich dies als Geschäftslogik betrachte und der Meinung bin, dass Option 2 ein höheres Risiko für die Einführung fehlerhafter Daten in das System darstellt. Welche Option bevorzugen Sie oder gibt es ein anderes Design, das besser zu diesem Szenario passt als die beiden beschriebenen Optionen?
Bearbeiten (Komplexität der Validierungen)
Die Validierungsfälle, die vorerst aufgetreten sind, sind relativ einfach. Der Feldwert muss z. B. numerisch, ein Datum, ein Datum mit einer Uhrzeit oder ein vorhandener Wert in einer Datenbankspalte sein. Ich vermute jedoch, dass die Komplexität mit der Zeit allmählich zunimmt. Zum Beispiel muss die Validierungslösung unter Berücksichtigung der Internationalisierung erstellt werden - Dinge wie Datumsangaben können in einer länderspezifischen Syntax eingegeben werden.
Ich habe mich entschlossen, vorerst mit Option 1 fortzufahren und darauf zu achten, dass dem Domänenmodell nicht zu viele Verantwortlichkeiten zugewiesen werden. Diejenigen, die sich einer ähnlichen Situation gegenübersehen, möchten möglicherweise auch die damit verbundenen Fragen überprüfen. Validierung und Autorisierung in der Schichtarchitektur und Validierung der Dateneingabe - Wo? Wie viel? .