Überprüfung der sauberen Architektur in der Domäne im Vergleich zur Datenpersistenzschicht?

12

Ich lerne sauber und überlege daher sehr dramatisch, wie ich Software entwerfe und schreibe.

Ich habe eine Sache, mit der ich immer noch ringe, aber für Geschäftsregeln wie "Beim Speichern von Updates für einen Artikel, zuerst laden Alle Liste der Artikel, die ich zum Anzeigen / Bearbeiten usw. habe, bestätigen, dass dieser Artikel in der Liste ist, und dass die Elementkategorie derzeit nicht für die Verwendung gesperrt ist (und andere Regeln usw. usw.) ".., da dies eine (komplexe, aber nicht atypische) Geschäftsregel ist und daher in der Anwendungsdomäne behandelt werden sollte, anstatt die Geschäftslogik zu verschieben die DB / Persistenz-Schicht.

Es scheint mir jedoch, dass zur effizienten Überprüfung dieser Bedingungen häufig am besten eine gut gestaltete Datenbankabfrage durchgeführt wird, anstatt alle Daten in die Anwendungsdomäne zu laden ...

Was ist ein empfohlener Ansatz oder einige Artikel von Onkel Bob, die sich ohne vorzeitige Optimierung mit dieser Frage befassen? Oder würde er sagen "Validieren in der Domain, bis es ein Problem wird"?

Ich habe wirklich Mühe, gute Beispiele / Beispiele für etwas anderes als die grundlegendsten Anwendungsfälle zu finden.

Aktualisieren:

Hallo zusammen, danke für die Antworten. Ich hätte klarer sein sollen, ich habe lange Zeit (meistens Web-App) Software geschrieben und definitiv bereits alle Themen erlebt und bin damit einverstanden, die Sie gemeinsam beschreiben (Validierung durch das Backend, Vertrauen in Kundendaten im Allgemeinen nicht Verfolgen Sie die Roheffizienz nur bei Bedarf, erkennen Sie jedoch die Stärken der DB-Tools an, wenn diese verfügbar sind (usw. usw.), und durchlaufen Sie den Lernlebenszyklus des Entwicklers "Alles zusammenwerfen", um "einen riesigen Fettregler mit N-Ebenen-Anwendungen zu erstellen", Code-Trends und jetzt den Clean / Single Responsibility-Stil usw. wirklich zu mögen und zu untersuchen, im Grunde genommen als Ergebnis einiger Projekte, die sich in letzter Zeit zu ziemlich klobigen und weit verbreiteten Geschäftsregeln entwickelten, als sich die Projekte weiterentwickelten und weitere Kundenanforderungen ans Licht kamen.

Insbesondere beschäftige ich mich mit der Architektur im sauberen Stil im Zusammenhang mit der Erstellung von REST-APIs für kundenorientierte und interne Funktionen, bei denen viele der Geschäftsregeln möglicherweise viel komplexer sind als im Grunde jedes Beispiel, das Sie im Internet sehen (Auch von den Leuten der Clean / Hex-Architektur selbst).

Ich habe also wirklich gefragt (und nicht klar angegeben), wie Clean und eine REST-API zusammenpassen würden, wo die meisten MVC-Inhalte, die Sie heutzutage sehen, Validatoren für eingehende Anforderungen haben (z. B. FluentValidation-Bibliothek in .NET), aber wo viele Meine "Validierungs" -Regeln lauten nicht so sehr "ist dies eine Zeichenfolge mit weniger als 50 Zeichen", sondern mehr "kann dieser Benutzer, der diesen Benutzer / Interaktor aufruft, diesen Vorgang für diese Datensammlung ausführen, da ein verwandtes Objekt derzeit von Team X gesperrt ist bis später im Monat etc etc "... diese Art von tiefgreifenden Validierungen, bei denen VIELE Geschäftsdomänenobjekte und Domänenregeln anwendbar sind.

Sollte ich diese Regeln in eine bestimmte Art von Validator-Objekttyp umwandeln, um jeden Usecase-Interaktor zu begleiten (inspiriert vom FluentValidator-Projekt, aber mit mehr Geschäftslogik und Datenzugriff), sollte ich die Validierung wie ein Gateway behandeln, sollte ich Setzen Sie diese Validierungen in ein Gateway (was ich für falsch halte) usw. usw.

Als Referenz gehe ich auf einige Artikel wie diesen ein , aber Mattia diskutiert nicht viel über Validierung.

Aber ich denke, die kurze Antwort auf meine Frage ähnelt der Antwort, die ich akzeptiert habe: "Es ist nie einfach und es kommt darauf an".

Dale Holborow
quelle
2
Es gibt oft einen Unterschied zwischen "richtig" und "praktisch". Welche bevorzugen Sie angesichts der Wahl?
Robert Harvey
"Alle Liste der Elemente laden" sieht nicht nach einer Geschäftsregel aus, sondern scheint zu sehr auf Implementierungsdetails einzugehen. Wenn Sie die Regel mithilfe einer Datenbankabfrage erfüllen können, ohne etwas zu laden, warum lautet die Regel "Laden"?
Hören Sie auf, Monica

Antworten:

31

Die Validierung der Dateneingabe ist eines der Dinge, bei denen jeder versucht, sie rein und sauber zu machen, und (wenn er schlau ist) schließlich aufgibt, weil es so viele konkurrierende Bedenken gibt.

  • Die UI-Schicht muss einige Validierungsformen direkt auf der Client-Seite / dem Client-Formular durchführen, um dem Benutzer Echtzeit-Feedback zu geben. Andernfalls verbringt der Benutzer viel Zeit damit, auf Feedback zu warten, während eine Transaktion über das Netzwerk gesendet wird.

  • Da der Client häufig auf einem nicht vertrauenswürdigen Computer ausgeführt wird (z. B. in fast allen Webanwendungen), müssen diese Validierungsroutinen erneut serverseitig ausgeführt werden, wenn der Code vertrauenswürdig ist.

  • Einige Formen der Validierung sind aufgrund von Eingabebeschränkungen implizit. Beispielsweise kann ein Textfeld nur eine numerische Eingabe zulassen. Dies bedeutet, dass Sie möglicherweise kein "Ist es numerisch?" Haben. Validator auf der Seite, aber Sie benötigen noch irgendwo einen im Back-End, da UI-Einschränkungen umgangen werden könnten (z. B. durch Deaktivieren von Javascript).

  • Die UI-Schicht muss einige Formen der Validierung am Service-Perimeter durchführen (z. B. serverseitiger Code in einer Webanwendung), um das System vor Injection-Angriffen oder anderen böswilligen Formen der Dateneingabe zu schützen. Manchmal befindet sich diese Validierung nicht einmal in Ihrer Codebasis, z . B. bei der Validierung von ASP.NET-Anforderungen .

  • Die UI-Schicht muss einige Validierungsformen durchführen, um vom Benutzer eingegebene Daten in ein Format zu konvertieren, das die Business-Schicht verstehen kann. Beispielsweise muss die Zeichenfolge "26.06.2017" in ein DateTime-Objekt in der entsprechenden Zeitzone umgewandelt werden.

  • Die Geschäftsschicht sollte die meisten Formen der Validierung durchführen, da sie theoretisch zur Geschäftsschicht gehören.

  • Einige Validierungsformen sind auf Datenbankebene effizienter, insbesondere wenn referenzielle Integritätsprüfungen erforderlich sind (z. B. um sicherzustellen, dass ein Statuscode in der Liste der 50 gültigen Status enthalten ist).

  • Einige Formen der Validierung müssen im Zusammenhang mit einer Datenbanktransaktion aufgrund von Parallelitätsproblemen erfolgen, z. B. muss das Reservieren eines eindeutigen Benutzernamens atomar sein, damit ein anderer Benutzer ihn während der Verarbeitung nicht abruft.

  • Einige Formen der Validierung können nur von Drittanbietern durchgeführt werden, z. B. wenn überprüft wird, ob eine Postleitzahl und ein Städtename zusammenpassen.

  • Im gesamten System können auf mehreren Ebenen Nullprüfungen und Datenkonvertierungsprüfungen durchgeführt werden, um angemessene Fehlermodi bei Vorhandensein von Codefehlern sicherzustellen.

Ich habe gesehen, dass einige Entwickler versucht haben, alle Validierungsregeln in der Geschäftsschicht zu kodifizieren, und dass die anderen Schichten sie dann aufrufen, um die Geschäftsregeln zu extrahieren und die Validierung auf einer anderen Schicht zu rekonstruieren. Theoretisch wäre das großartig, weil Sie am Ende eine einzige Quelle der Wahrheit haben. Aber ich habe noch nie gesehen, dass dieser Ansatz etwas anderes bewirkt, als die Lösung unnötig zu komplizieren, und er endet oft sehr schlecht.

Wenn Sie sich also umbringen, um herauszufinden, wohin Ihr Validierungscode geht, sollten Sie sich beraten lassen. Bei einer praktischen Lösung auch für ein mäßig komplexes Problem wird der Validierungscode an mehreren Stellen eingesetzt.

John Wu
quelle
Wenn Sie der Meinung sind, dass Ihre Benutzeroberfläche das gesamte Feedback der Benutzer verwaltet, können Sie den größten Teil der Validierungsprüfung in der Datenbank verschieben und nur das, was Sie nicht können, auf der Geschäftsebene behalten. Ein Problem tritt auf, wenn Sie eine vollständige Backend-API mit einer sehr detaillierten Fehlerbehebung für Nachrichten entwerfen.
Walfrat
2

Die Validierung ist Teil der Geschäftsschicht.

Der Punkt ist: Geschäftslogik in DAOs macht das Konzept von DAOs ungültig. Die Validierung in einer höheren Ebene führt zu einer redundanten Validierung, wenn Sie Geschäftsvorgänge von einem anderen Anwendungsfall aus aufrufen.

Vielleicht bewerten Sie etwas Sicherheit in der Benutzeroberfläche. Dies ist jedoch optional, da die gesicherten Domänenobjekte die wichtige Aufgabe übernehmen. In der Benutzeroberfläche werden Komponenten abhängig von den Berechtigungen des aktuell angemeldeten Benutzers sichtbar oder unsichtbar. Dies ist jedoch nur ein Teil der Benutzererfahrung. Sie möchten nicht, dass der Benutzer jedes Mal auf Sicherheitsausnahmen stößt, wenn er versucht, eine Aktion auszuführen, die er nicht ausführen darf.

oopexpert
quelle
2

Vielleicht möchten Sie Ihre Sichtweise überprüfen, wer was im Hinblick auf die Validierung tut. Ist es die Datenbank, in der Sie wissen, dass Sie mit der Datenbank arbeiten? Oder handelt es sich um einen Dienst (der zufällig von DB-Vorgängen unterstützt und gesteuert wird)? In meinem Projekt hat jeder aggregierte Stamm eine Liste von Gruppen, die ihn lesen können, und eine Liste von Modifikatoren. Wenn der Code nach einem bestimmten Stamm oder einer Liste von Wurzeln sucht, die der Benutzer sehen kann, werden alle Details hinter einem Dienst verborgen, der die Benutzer-ID und die zusätzlichen Teile des Suchkontexts verwendet, z. B. wo die Kachel mit „bla“ beginnt. Dem Code ist es egal, dass die Datenbank eine vorhandene Prüfung durchführt, um festzustellen, ob die Benutzergruppen in den Lesergruppen vorhanden sind. Es wird lediglich eine Liste mit oder ohne Inhalt erwartet, die darauf basiert, was auch immer der Dienst, der nur vertraglich festgelegt ist, bietet.

Dies gilt für alle Ebenen. Die Einheitlichkeit der Validierung ist der Schlüssel. Stellen Sie so viel wie möglich von Ihrer Validierung in die Domain. Geben Sie Einschränkungen mit Ihrer API zurück. Ich denke am Ende nicht an Einschränkungen, die von der X-Bibliothek oder dem Z-Speicher kommen, sondern vom Service.

Virmundi
quelle
0

Wenn eine Validierungslogik am einfachsten und klarsten in Form einer Datenbankabfrage ausgedrückt wird, haben Sie Ihre Antwort. Aber Effizienz sollte nur ein Problem sein , wenn Sie ein bekanntes Performance - Problem haben, sonst ist es verfrüht Optimierung.

JacquesB
quelle