Praktiken für Domänenmodelle in Javascript (mit Frameworks)

8

Dies ist eine Frage, mit der ich mich eine Weile beschäftigt habe und nach der ich gesucht und nichts gefunden habe: Was sind die akzeptierten Praktiken beim Duplizieren von Domänenmodellen in Javascript für eine Webanwendung, wenn ein Framework wie Backbone verwendet wird? oder Knockout?

Sollten wir bei einer nicht trivialen Webanwendung mit einer Reihe von Domänenmodellen auf der Serverseite diese Modelle in der Webanwendung duplizieren (siehe Beispiel unten)? Oder sollten wir die dynamische Natur nutzen, um diese Modelle vom Server zu laden?

Meiner Meinung nach bestehen die Argumente für das Duplizieren der Modelle darin, die Validierung von Feldern zu vereinfachen und sicherzustellen, dass tatsächlich vorhandene Felder vorhanden sind usw. Mein Ansatz besteht darin, den clientseitigen Code wie eine fast separate Anwendung zu behandeln und triviale Dinge zu tun selbst und nur für Daten und komplexe Vorgänge auf den Server angewiesen (für die Daten erforderlich sind, über die die Clientseite nicht verfügt). Ich denke, dass die Behandlung des clientseitigen Codes wie eine Trennung zwischen Entitäten von einem ORM und den Modellen ist, die mit der Ansicht in der UI-Ebene verwendet werden: Sie haben möglicherweise dieselben Felder und beziehen sich auf dasselbe Domänenkonzept, sind jedoch unterschiedlich Dinge.

Andererseits scheint es mir, dass das Duplizieren dieser Modelle auf der Serverseite eine eindeutige Verletzung von DRY darstellt und wahrscheinlich zu unterschiedlichen Ergebnissen auf der Client- und Serverseite führt (wobei ein Teil aktualisiert wird, der andere jedoch nicht ). Um diese Verletzung von DRY zu vermeiden, können wir einfach die Dynamik von Javascripts verwenden, um die Feldnamen und Daten vom Server abzurufen, sobald sie benötigt werden.

Also: Gibt es akzeptierte Richtlinien, wann (und wann nicht) Sie sich in diesen Situationen wiederholen sollten? Oder ist dies eine rein subjektive Sache, basierend auf dem Projekt und den Entwicklern?

Beispiel

Serverseitiges Modell

class M 
{
    int A
    DateTime B
    int C
    int D = (A*C)
    double SomeComplexCalculation = ServiceLayer.Call();
}

Client-seitiges Modell

function M(){
    this.A = ko.observable();
    this.B = ko.observable();
    this.C = ko.observable();
    this.D = function() { return A() * C(); }
    this.SomeComplexCalculation = ko.observalbe();
    return this;
}l
M.GetComplexValue = function(){
    this.SomeComplexCalculation(Ajax.CallBackToServer());
};

Ich weiß , diese Frage ist ganz ähnlich wie diese , aber ich denke , das mehr ist über fast ganz die Web - Anwendung auf dem Server Aufhebung der Bindung, wo die Frage nach nur im Fall von komplexen Berechnungs dies zu tun ist.

Andy Hunt
quelle
Geht es bei Ihrer Frage eher darum, wie Sie Objektinstanzen auf der JS-Seite für entkoppelte Komponenten verwalten, oder eher um die Kommunikation zwischen Client und Server? In Bezug auf M.getComplexValue()möchten Sie möglicherweise auch das "Promise" -Muster untersuchen, um die Callback-Hölle zu minimieren und gleichzeitig zu ermöglichen, dass alle Vorgänge (möglicherweise) asynchron sind.
Darien
Es geht mehr darum, ob definierte Objekte in JS (wie im Beispiel) oder ein anonymes Objekt mit dynamisch ausgefüllten Feldern verwendet werden sollen
Andy Hunt

Antworten:

0

Ich denke, gute Designmuster und ein Framework wie Breeze können Ihnen helfen. Wiederholen Sie das Domänenmodell nicht erneut auf dem Client, sondern lassen Sie es auf dem Server, sondern verwenden Sie Breeze, um das Modell auf den Client zu ziehen.

Hier ist ein großartiges Beispiel für die Verwendung von Breezejs mit dem Repository und der Arbeitseinheit.

https://github.com/yagopv/DurandalAuth

Das Domänenmodell wird auf dem Server gespeichert, und Breeze liest die Metadaten und erstellt die Entitäten lokal vom Server aus. Ich denke, das ist eine großartige Lösung für Ihr Problem. Sie erhalten lokalen Zugriff auf den Entity Framework-Typ lokal über JS und können Ihr Modell auf dem Server behalten. Ich denke, es passt gut zu den Themen, die Sie in Ihrer Frage angesprochen haben.

Roger Brogan
quelle
2
Wie beantwortet dies die gestellte Frage? So wie es aussieht, liest sich dies eher wie eine Spam-Werbung.
Mücke
1
Es ist eine ziemlich direkte Antwort. Die Frage ist, das Domänenmodell auf dem Client erneut zu wiederholen. Meine Antwort lautet: Lassen Sie es nicht auf dem Server, sondern lassen Sie das Modell einfach auf den Client ziehen. Ich bin nicht mit Brise oder Durandal verbunden. Ich finde die Frameworks einfach nützlich.
Roger Brogan
3

Ihre eigentliche Frage ist etwas allgemeiner, daher ist sie schwer zu beantworten, aber Ihr Beispiel für die Formularvalidierung ist etwas spezifischer, daher werde ich versuchen, mich an diese zu halten.

Wie Sie sagten, sollten Sie immer so trocken wie möglich sein. Das ist eine gute Sache, die Sie als Entwickler beachten sollten. Sie sollten jedoch zwischen den Dingen unterscheiden, die ihnen ähnlich sind, und Sie sollten vermeiden, sie mit den Dingen zu wiederholen, die sie ähnlich machen, aber sie haben unterschiedliche Zwecke .

Kommen wir zu Ihrem Beispiel für die Formularvalidierung. Der Zweck Ihres Validierungscodes auf dem Server besteht darin, sicherzustellen, dass Sie die E-Mail-Adresse des Benutzers haben, die Sie beispielsweise in die Datenbank aufnehmen können. Da es für Ihren Registrierungsprozess ein Muss ist, die E-Mail-Adresse des Benutzers zu haben, überprüfen Sie dies während des Registrierungsprozesses.

Aber was ist der Zweck Ihres clientseitigen JavaScript-Codes? Ja, es wird die Validierung im E-Mail-Eingabefeld durchgeführt, aber die ganze Idee ist: Um zu überprüfen, ob der Benutzer seine E-Mail-Adresse bereits eingegeben hat, wenn nicht, wird ihm eine Warnung angezeigt, bevor er an den Server gesendet wird! Der Zweck Ihrer clientseitigen Formularüberprüfung besteht also darin, keine unbrauchbaren Daten mehr an den Server zu senden und nach einigen Sekunden eine Fehlermeldung anzuzeigen, um das Antragsformular erneut zu senden. Warum? weil es für Benutzer ärgerlich ist. Denken Sie jetzt, Sie sollten Ihre Formularüberprüfungsfunktion nur auf dem Server behalten? Nein, weil sie unterschiedliche Zwecke haben.

Der Zweck der Formularvalidierung auf der Clientseite besteht nicht darin, dass ich Benutzern nicht vertrauen kann. Schauen wir uns das an , aber es ist eher eine UX-Sache, bei der Sie versuchen, die Kommunikation mit dem Server zu vermeiden, nur um die Validierungsfehlermeldung zu erhalten. Der Zweck der Formularüberprüfung auf der Serverseite besteht jedoch darin, dass ich den Benutzern nicht vertrauen kann. Lassen Sie uns sehen, was sie von mir verlangen , und ein Benutzer kann auch eine API-Anforderung sein - ohne einen menschlichen Benutzer auf der Client-Seite.

Wenn Sie es so betrachten, wäre Ihr Formularvalidierungsbeispiel völlig in Ordnung, ohne dass Sie sich nass fühlen.

Versuchen Sie in Bezug auf Ihre eigentliche Frage nicht, alles auf dem Server oder alles auf dem Client zu behalten. Es kommt wirklich auf die Aufgabe an. Angenommen, ich muss eine große CSV-Datei für den Benutzer analysieren und habe nur hundert Benutzer auf der Website und weiß, dass ich mobile Benutzer habe. Dann kann ich diese Datei auf dem Server analysieren und dann eine ordnungsgemäße einfache Ausgabe ausgeben -Um Digest-Markup für den Client. Wenn ich jedoch Millionen von Benutzern habe, würde ich versuchen, die Datei auf ihren Computern zu analysieren - indem ich ihre Webbrowser verwende, um ihre Verarbeitungsleistung zu nutzen und ein Ausbrennen unseres Servers zu vermeiden. Die Analysefunktion kann sich also entweder auf dem Server oder auf dem Client befinden, was auch immer sinnvoller ist.

Wenn Sie sich jedoch nicht sicher sind, wo Sie Ihre Sachen aufbewahren sollen, sollten Sie sie auf dem Server aufbewahren und die Ergebnisse dann den Benutzern bereitstellen. Vermeiden Sie doppelten Code sowohl auf dem Server als auch auf dem Client.

Mahdi
quelle
Würde gerne wissen, warum die Antwort abgelehnt wurde. Ich weiß es wirklich zu schätzen, wenn Sie auch Ihre Gedanken teilen.
Mahdi